频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

将数据库中二进制数据以异步方式写入磁盘

来源: 作者: 出处:巧巧读书 2006-09-19 进入讨论组

  方式一:一次获取,异步写入
/// <summary>
/// 缓冲区大小
/// </summary>
public const int numPixels = 512 * 512;
/// <summary>
/// 将数据文件写入磁盘
/// </summary>
/// <param name="strSql"></param>
/// <returns></returns>
public static bool MakeFileWithWriteListByAdapter(string strSql,out string strErr)
{
if(File.Exists(ConfigProxy.GetValueByKey("ListFile")))File.Delete(ConfigProxy.GetValueByKey("ListFile"));
DataTable objTable;
if(!OleDataBaseProxy.ExecuteSql(strSql,out objTable,out strErr))return false;
string outputPath = ConfigProxy.GetValueByKey("OutputPath");
if(objTable.Rows.Count < 1) return false;
string strDirectory = outputPath + "\\";
if(!Directory.Exists(strDirectory)) Directory.CreateDirectory(strDirectory);
for(int i = 0;i< objTable.Rows.Count; i ++)
{

string fileName = objTable.Rows[i]["附件名称"].ToString();
//记录输出列表
LogProxy.WriteList(strDirectory + fileName);
//获取文件数据
byte [] ImageContent = (byte[])objTable.Rows[i]["附件内容"];
AutoResetEvent manualEvent = new AutoResetEvent(false);
FileStream fStream =
new FileStream(strDirectory + fileName,FileMode.Create,
FileAccess.ReadWrite, FileShare.None, 4096, true);
IAsyncResult asyncResult = fStream.BeginWrite(
ImageContent, 0, ImageContent.Length,
new AsyncCallback(EndWriteCallback),
new State(fStream, manualEvent));
manualEvent.WaitOne(5000, false);
fStream.Close();
}
strErr = "";
return true;
}
class State
{
public FileStream fStream;
public AutoResetEvent autoEvent;

public State(FileStream fStream, AutoResetEvent autoEvent)
{
this.fStream = fStream;
this.autoEvent = autoEvent;
}
}
static void EndWriteCallback(IAsyncResult asyncResult)
{

State stateInfo = (State)asyncResult.AsyncState;
int workerThreads;
int portThreads;
try
{
ThreadPool.GetAvailableThreads(out workerThreads,
out portThreads);
stateInfo.fStream.EndWrite(asyncResult);
Thread.Sleep(1500);
}
finally
{
stateInfo.autoEvent.Set();
}
}

方式二:联机读取,异步写入

/// <summary>
/// 缓冲区大小
/// </summary>
public const int numPixels = 512 * 512;
/// <summary>
/// 将数据文件写入磁盘
/// </summary>
/// <param name="strSql"></param>
/// <returns></returns>
public static bool MakeFileWithWriteListByReader(string strSql,out string strErr)
{
if(File.Exists(ConfigProxy.GetValueByKey("ListFile")))File.Delete(ConfigProxy.GetValueByKey("ListFile"));
string outputPath = ConfigProxy.GetValueByKey("OutputPath");
string strDirectory = outputPath + "\\";
if(!Directory.Exists(strDirectory)) Directory.CreateDirectory(strDirectory);
System.Data.OleDb.OleDbCommand cmd = new OleDbCommand();
OleDbConnection Cnn = new OleDbConnection(ConfigProxy.GetValueByKey("OleConnectionString"));
cmd.Connection = Cnn;
cmd.CommandText = strSql;
//开启连接
try
{
Cnn.Open();
}
catch(Exception Err)
{
strErr = Err.Message;
return false;
}
byte[] pixels = new byte[numPixels];
OleDbDataReader reader = cmd.ExecuteReader();
byte[]ImageContent;
//逐条处理
while(reader.Read())
{
string fileName = reader.GetString(1);
//记录输出列表
LogProxy.WriteList(strDirectory + fileName);
//获取文件数据
ImageContent = new byte[Convert.ToInt64(reader.GetString(7))];
reader.GetBytes(6,0,ImageContent,0,Convert.ToInt32(reader.GetString(7)));
AutoResetEvent manualEvent = new AutoResetEvent(false);
FileStream fStream =
new FileStream(strDirectory + fileName,FileMode.Create,
FileAccess.ReadWrite, FileShare.None, 4096, true);
IAsyncResult asyncResult = fStream.BeginWrite(
ImageContent, 0, ImageContent.Length,
new AsyncCallback(EndWriteCallback),
new State(fStream, manualEvent));
manualEvent.WaitOne(5000, false);
fStream.Close();
}
reader.Close();
//关闭连接
if(Cnn.State == System.Data.ConnectionState.Open)
{
Cnn.Close();
}
strErr = "";
//释放资源
Cnn.Dispose();
cmd.Dispose();
GC.Collect();
return true;
}
class State
{
public FileStream fStream;
public AutoResetEvent autoEvent;

public State(FileStream fStream, AutoResetEvent autoEvent)
{
this.fStream = fStream;
this.autoEvent = autoEvent;
}
}
static void EndWriteCallback(IAsyncResult asyncResult)
{

State stateInfo = (State)asyncResult.AsyncState;
int workerThreads;
int portThreads;
try
{
ThreadPool.GetAvailableThreads(out workerThreads,
out portThreads);
stateInfo.fStream.EndWrite(asyncResult);
Thread.Sleep(1500);
}
finally
{
stateInfo.autoEvent.Set();
}
}

两种方式的比较:

方式一:适合于数据库负载较大,二进制数据大小已知的情况;
方式二:适合于数据库负载较小,二进制数据大小未知的情况;

其中:两种方式的异步机制都是相同的,没有任何区别;异步机制的优点在于充分发挥了操作系统的优点
注意:在需要对性能进行同比测试的上下文中不能采用异步机制而必须尽量采用同步机制,以提高真实性浏览地址: http://www.qqread.com/dotnet/h233632.html 更多文章 更多内容请看数据库专栏数据库处理专题城域网专题专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
最新论坛文章
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章