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

原创 2005年02月28日 19:47:00

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

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

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

将数据以二进制流方式写入数据库

将数据以二进制流方式写入数据并再还原成原来的文件,编辑再写入 根据目前自己在项目里做的东西,也学到的东西,总结一下: 一、需求:将结构化数据以二进制格式保存在数据库中(别说这样不好,别说建议...

将数据以二进制和URL的方式存入数据库并且请求出json

在当下文件存入数据库的格式无非有两种: 一种是存入直白的URl 另一种是将文件以二进制字节数组的形式存入数据库 相对来说二进制字节数组会占用较大的内存空间,所以当前普遍用URL进行存储与请求第一...

asp.net 二进制数据写入及读出以 图片方式展现

前端时间做视频智能监控,第三方自动拍照时保存至数据库,以二进制存入。 为了团队更方便后续关于此功能的开发。在此做下简易的总结:1. 数据库里 用 varbinary(MAX) , PerHomeL...

C#读取本地磁盘下指定路径下的所有图片,并以二进制存入数据库

C#读取本地磁盘下指定路径下的所有图片,并以二进制流存入数据库1.读取本地磁盘下指定路径下的所有图片/// /// 读取本地磁盘下指定路径下的所有图片 /// ...
  • ailo555
  • ailo555
  • 2016年02月21日 20:11
  • 1963

C/C++快速读写磁盘数据的方法-块读取/异步/优化分析算法/内存文件映射的原理和使用

快速读写磁盘数据的方法: 1.一下子将数据读取到内存的(无论是文本还是二进制),而不是一行行的读取。 2.异步的IO,创建多线程,或者使用重叠IO,IO复用,异步的事件回调通知机制(可以用事件对象,...

jquery 异步请求数据的三种方式

  • 2010年12月20日 01:27
  • 58KB
  • 下载

使用Jquery的Ajax异步提交有二进制数据的表单实现方案

1. 用H5的FormData对象来构造表单数据: var form = $("#form")[0]; var formData = new FormData(form); 2.contentTy...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:将数据库中二进制数据以异步方式写入磁盘
举报原因:
原因补充:

(最多只允许输入30个字)