`

异步读取大文件的改进

 
阅读更多
这个是异步读取大文件
的改进版。功能上更简洁一些,不过对同时访问同一个文件的互斥操作还没做好。

其改进主要是以下几点:

一:FileStream.Read的调用改为BeginRead,

二:报告进度的方法挪到BeginRead的回调方法之中。

三:在异步读取完成或是取消异步读取时,关闭文件流。

四:每次读取的内容放在读取进度报告之中,并记录下当前已读取了多少,及开始读取的位置。

五:由于是大文件,因此,在读取完成的事件参数里不记录读取内容。只记录完成时的时间。

经过总结发现,异步读取对小文件(小于1M)不起作用,还不如用File.ReadAllText来的快,只有在文件大于100M时效果比较明显.不太清楚是什么原因,可能是异步调用时线程切换比较费时吧!

下面是源码。有空的话做成教学课件放到自己的在线教育网站上请各位指点一下。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data ;
using System.Data.SqlClient ;
using System.Threading ;
using System.ComponentModel ;
using System.Collections;
using System.Collections.Specialized;
using System.IO;

namespace AsyncIO.FileIO
{
public class ReadBLOBFileCompletedEventArgs : AsyncCompletedEventArgs
{
public FileStream FS;
public ReadBLOBFileCompletedEventArgs(FileStream fs ,Exception e,bool canncel,object state)
: base(e, canncel, state)
{
FS = fs;
}
}
public class ReadBLOBFileProgressEventArgs : ProgressChangedEventArgs
{

byte[] buffer;
public ReadBLOBFileProgressEventArgs(int Percentage, object state,byte[] _Buffer)
: base(Percentage, state)
{

buffer = _Buffer;

}

public byte[] Buffer
{
get { return buffer; }
}
}
public delegate void ReadBLOBFileCompletedEventHander(object sender, ReadBLOBFileCompletedEventArgs e);
public delegate void ReadBLOBFileProgressEventHandler(object sender ,ReadBLOBFileProgressEventArgs e);



public class AsyncReadWriteLargeFile
{
private delegate void ReadBLOBFileWorker(FileStream fs, object userToken);

public event ReadBLOBFileCompletedEventHander ReadBLOBFileCompleated;
public event ReadBLOBFileProgressEventHandler ReadBLOBFileProgressChanged;
#region Fire Event
protected virtual void OnReadBLOBFileCompleated(ReadBLOBFileCompletedEventArgs args)
{
if (ReadBLOBFileCompleated != null)
ReadBLOBFileCompleated(this, args);
}
protected virtual void OnReadBLOBFileProgressChanged(ReadBLOBFileProgressEventArgs args)
{
if (ReadBLOBFileProgressChanged != null)
ReadBLOBFileProgressChanged(this, args);
}
#endregion

SendOrPostCallback _completed;
SendOrPostCallback _report;
HybridDictionary _task = new HybridDictionary();

#region SendOrPostCallback Function
void compeleted(object state)
{
ReadBLOBFileCompletedEventArgs e = state as ReadBLOBFileCompletedEventArgs;
e.FS.Close();
OnReadBLOBFileCompleated(e);
}
void report(object state)
{
ReadBLOBFileProgressEventArgs e = state as ReadBLOBFileProgressEventArgs;
OnReadBLOBFileProgressChanged(e);
}
#endregion

void Init()
{
_completed = new SendOrPostCallback(compeleted);
_report = new SendOrPostCallback(report);
}
public AsyncReadWriteLargeFile()
{
Init();
}
public void CancelAsync(Guid id)
{
BLOBFileState op = _task[id] as BLOBFileState;
if (op != null)
{
ReadBLOBFileCompletedEventArgs e = new ReadBLOBFileCompletedEventArgs(op.FS, null, true, id);
op.AsyncOp.PostOperationCompleted(_completed, e);
lock (_task.SyncRoot)
{
_task.Remove(id);
}
}
}
public void ReadAsync(string xmlFile,Guid id)
{

ReadBLOBFileWorker work = new ReadBLOBFileWorker(worker);
AsyncOperation op = AsyncOperationManager.CreateOperation(id);
lock (_task.SyncRoot)
{
if(_task.Contains(id)==false )
{
FileStream fs = new FileStream(xmlFile, FileMode.Open);
BLOBFileState st = new BLOBFileState(fs,op);
_task.Add(id, st);
work.BeginInvoke(fs, st, null, null);
}
}

}

void worker(FileStream fs, object userToken)
{
BLOBFileState st = userToken as BLOBFileState;
AsyncOperation op = st.AsyncOp;
BLOBFileReadBufferState rf = new BLOBFileReadBufferState(fs, new byte[0x1000],op,0);
fs.BeginRead(rf.Buffer, 0, 0x1000, new AsyncCallback(readCallback), rf);
}
void readCallback(IAsyncResult ar)
{
BLOBFileReadBufferState rf = ar.AsyncState as BLOBFileReadBufferState;
int res = rf.FS.EndRead(ar);
if (res > 0)
{
rf.HasRead =rf.StartPos +res ;
float p = (float)rf.HasRead / (float)rf.FS.Length;
int cx = (int)(p * 100);
byte[] buffer = new byte[res];
Array.Copy(rf.Buffer, buffer, res);
ReadBLOBFileProgressEventArgs e = new ReadBLOBFileProgressEventArgs(cx, rf.AsyncOp.UserSuppliedState, buffer);
this._report(e);
BLOBFileReadBufferState bf2 = new BLOBFileReadBufferState(rf.FS, new byte[0x1000], rf.AsyncOp,rf.HasRead);
rf.FS.BeginRead(bf2.Buffer, 0, 0x1000, new AsyncCallback(readCallback), bf2);
}
else
{
rf.FS.Close();
ReadBLOBFileCompletedEventArgs e = new ReadBLOBFileCompletedEventArgs(rf.FS ,null, false, rf.AsyncOp.UserSuppliedState);
rf.AsyncOp.PostOperationCompleted(this._completed, e);
//this._completed(e);

}


}
internal class BLOBFileReadBufferState
{
public FileStream FS;
public byte[] Buffer;
public AsyncOperation AsyncOp;
public int StartPos;
public int HasRead;
public BLOBFileReadBufferState(FileStream fs, Byte[] buffer,AsyncOperation op,int startPos)
{
FS = fs;
Buffer = buffer;
AsyncOp = op;
StartPos = startPos;
}
}

internal class BLOBFileState
{
public FileStream FS;
public AsyncOperation AsyncOp;
public BLOBFileState(FileStream fs, AsyncOperation asyncOp)
{
FS = fs;
AsyncOp = asyncOp;

}
}
}
}

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术,...

    amlogic烧录工具最新版本

    1.改进一次读取的字节数 2.改进Secureboot的处理 V2.1.5 1.支持芯片905D2新流程 2.Platform.conf配置增加DDRSize,根据Size判断download的数据大小,兼容旧芯片 V2.1.3 1.更改烧录时MAC显示的问题,同时增加对BT,...

    ASP+Access+AJAX天气预报加强版_2010-1-18最新改进版

    全国各省市数据表里读取数据加载到下拉列表中,通过选择省和市,以AJAX异步传输方式获取天气信息,还可 以选择获取今天、明天和后天的天气信息。 配置说明: 1.不需做任何修改,直接设置成站点或虚拟目录即可,也...

    ASP+sql2000+AJAX天气预报加强版_2010-1-18最新改进版

    全国各省市数据表里读取数据加载到下拉列表中,通过选择省和市,以AJAX异步传输方式获取天气信息,还可 以选择获取今天、明天和后天的天气信息。 配置说明: 1.不需做任何修改,直接设置成站点或虚拟目录即可,也...

    写给大忙人看的JAVA SE 8

    8.5.1 读取文件行的流 173 8.5.2 遍历目录项的流 175 8.5.3 Base64编码 176 8.6 注解 177 8.6.1 可重复的注解 177 8.6.2 可用于类型的注解 179 8.6.3 方法参数反射 181 8.7 其他一些细微的改进 182 8.7.1 Null检查 ...

    ASP+sql2000+AJAX天气预报加强版-根据IP自动获取当地天气预报

    全国各省市数据表里读取数据加载到下拉列表中,通过选择省和市,以AJAX异步传输方式获取天气信息,还可 以选择获取今天、明天和后天的天气信息。 配置说明: 1.文件中的weather_Data_MDF.rar是数据文件,直接附加就...

    JAVA上百实例源码以及开源项目源代码

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术,...

    word-Count-Visitor-Pattern:这是使用数据结构和执行带有访客模式精巧的字数统计的实现

    字数访问者模式CS542设计模式2015年Spring项目分配编号04自述文件截止日期... 异步文件读取特定文件。 处理数据处理一种。 使用运行时可用的处理器API,可以获取特定计算机上可用的处理器数量,并产生那么多线程用于数

    es6学习笔记之Async函数的使用示例

    异步I/O不就是读取一个文件吗,干嘛要搞得这么复杂?异步编程的最高境界,就是根本不用关心它是不是异步。 async 函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案。下面就来看看关于async函数的两个...

    深入理解js 中async 函数的含义和用法

    异步I/O不就是读取一个文件吗,干嘛要搞得这么复杂?异步编程的最高境界,就是根本不用关心它是不是异步。 async 函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案。 二、async 函数是什么? 一句话...

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    12.2 使用流读写文件 12.2.1 文本文件 12.2.2 二进制文件 12.2.3 上传文件 12.2.4 使文件对多用户安全 12.2.5 压缩 12.3 序列化 12.4 总结 第13章 LINQ 13.1 LINQ基础 13.1.1 延迟执行 ...

    基于MySQL的数据库中间件Meituan-DBProxy.zip

    奇虎360公司开源的Atlas是优秀的数据库中间件,美团点评DBA团队针对公司内部需求,在其上做了很多改进工作,形成了新的高可靠、高可用企业级数据库中间件DBProxy,已在公司内部生产环境广泛使用,较为成熟、稳定。...

    DBTwin数据库集群与AlwaysOn的比较

    对于死锁或者执行时间过长等异常的SQL语句会在日志文件里记录下来,以利于改进和优化等等。AlwaysOn没有这些功能。 6. 技术服务 DBTwin数据库集群厂家和代理商提供性能优化、设计、运维等的咨询服务。AlwaysOn客户...

    ASP.NET4高级程序设计(第4版) 3/3

    12.2 使用流读写文件 414 12.2.1 文本文件 415 12.2.2 二进制文件 416 12.2.3 上传文件 417 12.2.4 使文件对多用户安全 419 12.2.5 压缩 423 12.3 序列化 423 12.4 总结 426 第13章 LINQ 427 ...

    2.ASP.NET.2.0.高级编程(第4版) [1/7]

    ASP.NET 2.0新增了50多个新服务器控件,类的数量也翻了一倍,其他许多方面也有很大的变化。本书介绍了ASP.NET 2.0中的每个新增特性和功能,以便读者把这些新技术应用于实践。.. 本书主要内容 ● 服务器控件的...

    Visual C++/Turbo C串口通信编程实践 及源代码-1

    2.4.1 改进一:ascii文本和二进制数据发送方式兼容 40 2.4.2 改进二:也许能解决内存泄漏 43 2.4.3 改进三:彻底关闭串口,释放串口资源 44 第3章 控件mscomm串口编程 46 3.1 mscomm控件介绍 46 3.1.1 vc中应用...

    asp.net知识库

    改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+总结 [ADO.NET]由数据库触发器引发的问题 为ASP.NET封装的SQL数据库访问类 DataTable.Select方法的性能问题 .NET 2.0里使用强...

    Visual C++/Turbo C串口通信编程实践及源代码-2

    2.4.1 改进一:ascii文本和二进制数据发送方式兼容 40 2.4.2 改进二:也许能解决内存泄漏 43 2.4.3 改进三:彻底关闭串口,释放串口资源 44 第3章 控件mscomm串口编程 46 3.1 mscomm控件介绍 46 3.1.1 vc中应用...

Global site tag (gtag.js) - Google Analytics