.NET开发

本类阅读TOP10

·NHibernate快速指南(翻译)
·vs.net 2005中文版下载地址收藏
·【小技巧】一个判断session是否过期的小技巧
·VB/ASP 调用 SQL Server 的存储过程
·?dos下编译.net程序找不到csc.exe文件
·通过Web Services上传和下载文件
·学习笔记(补)《.NET框架程序设计(修订版)》--目录
·VB.NET实现DirectDraw9 (2) 动画
·VB.NET实现DirectDraw9 (1) 托管的DDraw
·建站框架规范书之——文件命名

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
将数据库中二进制数据以异步方式写入磁盘

作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站

方式一:一次获取,异步写入
/// <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();
   }
  }

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

其中:两种方式的异步机制都是相同的,没有任何区别;异步机制的优点在于充分发挥了操作系统的优点
注意:在需要对性能进行同比测试的上下文中不能采用异步机制而必须尽量采用同步机制,以提高真实性




相关文章

相关软件