c# txt内存映射技术总结
对于大文件操作,readline 的方式读取文档,那操作起来跟蜗牛爬一样的慢了, 于是使用内存映射技术,
参考微软的这个使用方法说明
https://msdn.microsoft.com/zh-cn/library/dd997372(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
1: 主要用到下面两个方法,一个是打开一个文本,一个是对文本进行操作
using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(srcFile, FileMode.Open, "xyz", size)) using (mmf_reader = mmf.CreateViewAccessor(, portion1, MemoryMappedFileAccess.Read))
可以对文本按照位置提取相应内容,提取的内容可以使用byte方式 ,若是都为英文或者数字键盘符号的文档.这样节省很多资源
2:按照块提取会存在一个问题,你的分块肯定会破坏文档里边的整个行,所以我的方法是按照分块,确定块的附近换行符的位置.
3:根据换行符 确定了位置,把一个大文件分成块,当然也可以一次读入到内存,做进一步处理,你可以参考微软的帮助做相应的优化.
4: 打开一个新的保存文件,不破坏源文件,不在源文件上操作,
5:启动task[]线程组,每个块分配一个task去做相关处理.
6:for循环涉及到每块处理的先后顺序
Task[] tasks = new Task[t];
for (int i = ; i < mappedFiles.Count; i++)
{
tasks[i] = Task.Factory.StartNew(action, i);
tasks[i].Wait();
}
这里使用了Action 无返回值,和Fuc 带参数有返回值两种方式,我选择了前者 .
Action<object> action = (object obj) =>
{
}
7:还可以使用streamreader 对打开的文本进行操作
using (FileStream fs = new FileStream(TXT_FILE_PATH, FileMode.Open, FileAccess.ReadWrite))
{
long targetRowNum = ttargetRowNum + ;//目标行
long curRowNum = ;//当前行
FILE_SIZE = fs.Length;
using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "test", fs.Length, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, false))
{
long offset = ;
//int limit = 250;
int limit = ;
try
{
StringBuilder sbDefineRowLine = new StringBuilder();
do
{
long remaining = fs.Length - offset;using (MemoryMappedViewStream mmStream = mmf.CreateViewStream(offset, remaining > limit ? limit : remaining))
//using (MemoryMappedViewStream mmStream = mmf.CreateViewStream(offset, remaining))
{
offset += limit;
using (StreamReader sr = new StreamReader(mmStream))
{
//string ss = sr.ReadToEnd().ToString().Replace("\n", "囧").Replace(Environment.NewLine, "囧");
string ss = sr.ReadToEnd().ToString().Replace("\n", SPLIT_VARCHAR).Replace(Environment.NewLine, SPLIT_VARCHAR);
可以直接读取块到byte[] buffer 块 我用的这种
private static void SpiltFile(string srcFile, int portionSize)
{
string savedPath = @"\\stcsrv-c81\MMFeedHealthyDatacache\2016_07_10\Feedkeys\No_Process_test.txt";
FileInfo fi = new FileInfo(srcFile);
// total size in bytes
Int64 size = fi.Length;
object locker = new object();
object writeLock = new object();
List<MappedFile> mappedFiles = new List<MappedFile>();
Int64 fileToRead = size;//文件总的大小 portionSize = portionSize * * ; //每块大小 Int64 portion = (Int64)Math.Ceiling(size * 1.0 / portionSize); //分成多少块 Int64 fileOffset = ; MemoryMappedViewAccessor mmf_reader = null;
Stopwatch watch = Stopwatch.StartNew();
watch.Start();
Int64 fileSize = ;
using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(srcFile, FileMode.Open, "xyz", size))
{
//using (var writeMap = MemoryMappedFile.CreateFromFile(savedPath, FileMode.Create, "test", size, MemoryMappedFileAccess.ReadWrite))
//{
//bool mutexCreated;
//Mutex mutex = new Mutex(true, "testmapmutex", out mutexCreated);//进程间同步
Parallel.For(, portion, (i, ParallelLoopState) =>
{ //for (int i = 26; i < portion; i++)
//{
lock (locker)
{
fileSize = Math.Min(portionSize, fileToRead - portionSize * i);
if (fileSize > )
{
byte[] buffer;
using (mmf_reader = mmf.CreateViewAccessor(i * portionSize, fileSize, MemoryMappedFileAccess.Read))
{
buffer = new byte[fileSize];
mmf_reader.ReadArray(, buffer, , (int)fileSize);
mappedFiles.Add(new MappedFile
{
Offset = i * portionSize, //fileOffset,
Buffer = buffer,
FileSize = fileSize
});
} //fileToRead -= fileSize;
//lock (writeLock)
//{
//using (var writeMmf = MemoryMappedFile.OpenExisting("xyz"))
//{
// using (var writeAccessor = writeMmf.CreateViewStream(i * portionSize, fileSize))
// {
// var w = new BinaryWriter(new FileStream(savedPath, FileMode.Create, FileAccess.Write));
// //writeAccessor.WriteArray(i * portionSize, buffer, 0, buffer.Length);
// //writeAccessor.Write(buffer, 0, buffer.Length);
// w.Write(buffer);
// }
//} //using (MemoryMappedViewAccessor writeView = writeMap.CreateViewAccessor())
//{
// writeView.WriteArray(i * portionSize, buffer, 0, (int)fileSize);
//} }
//}
} });
} using (var writeMap = MemoryMappedFile.CreateFromFile(savedPath, FileMode.Create, "test", size, MemoryMappedFileAccess.ReadWrite))
{
using (MemoryMappedViewAccessor writeView = writeMap.CreateViewAccessor())
{
Parallel.For(, mappedFiles.Count, i =>
{
try
{
Monitor.Enter(locker);
writeView.WriteArray(mappedFiles[i].Offset, mappedFiles[i].Buffer, , (int)mappedFiles[i].FileSize);
}
catch (Exception)
{ throw;
}
finally
{
Monitor.Exit(locker);
} });
}
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
#region MyRegion
}
[csharp] view plain copy
public class MappedFile
{
public long Offset { get; set; }
public byte[] Buffer { get; set; }
public long FileSize { get; set; }
C# 中字符串string和字节数组byte[]的转换
string转byte[]:
byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str );
byte[]转string:
string str = System.Text.Encoding.Default.GetString ( byteArray );
string转ASCII byte[]:
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str );
ASCII byte[]转string:
string str = System.Text.Encoding.ASCII.GetString ( byteArray );
c# txt内存映射技术总结的更多相关文章
- C#大文件读取和查询--内存映射
笔者最近需要快速查询日志文件,文件大小在4G以上. 需求如下: 1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M. 2.希望查询1G以内容,能控制在20s左右. 刚开始觉得这个应该 ...
- 【转】C#大文件读取和查询--内存映射
笔者最近需要快速查询日志文件,文件大小在4G以上. 需求如下: 1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M. 2.希望查询1G以内容,能控制在20s左右. 刚开始觉得这个应该 ...
- linux编程之内存映射
一.概述 内存映射是在调用进程的虚拟地址空间创建一个新的内存映射. 内存映射分为2种: 1.文件映射 ...
- windows内存映射学习及帮助类实现
本文通过创建文件内存映射类,学习windows内存映射相关知识:创建内存映射文件后,可以按照内存操作方式操作文件:支持32位程序处理超过4G大小的文件. 感谢http://blog.csdn.net/ ...
- Java内存映射,上G大文件轻松处理
内存映射文件(Memory-mapped File),指的是将一段虚拟内存逐字节映射于一个文件,使得应用程序处理文件如同访问主内存(但在真正使用到这些数据前却不会消耗物理内存,也不会有读写磁盘的操作) ...
- JAVA NIO FileChannel 内存映射文件
文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...
- Python之mmap内存映射模块(大文本处理)说明
背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过 ...
- Java中用内存映射处理大文件
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如 ...
- 使用Java内存映射(Memory-Mapped Files)处理大文件
>>NIO中的内存映射 (1)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...
随机推荐
- [Linux]Ubuntu下安装Sublime-text 且 支持中文输入
------------------------------------------------------------------------------------------ 首先进行如下操作: ...
- 11.mysql-权限.md
目录 -- ***********五.mysql权限问题**************** -- mysql数据库权限问题:root :拥有所有权限(可以干任何事情) -- 权限账户,只拥有部分权限(C ...
- ArcGIS案例学习笔记-栅格数据分区统计(平均高程,污染浓度,污染总量,降水量)
ArcGIS案例学习笔记-栅格数据分区统计(平均高程,污染浓度,污染总量,降水量) 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:针对栅格数据,利用多边形面要 ...
- 关于在VS2008和VS2010中禁用及卸载Visual Assist X的方法研究——转载
禁用和启用 此方法对于VS2008和VS2010 都适用. 在VS2008或VS2010菜单栏中选择“VassistX”选项卡,找到“Enable/Disable Visual Assist X” ...
- 关于xml中自动提示功能的设置
我们在编写xml文件时如果有自动提示功能,将会事半功倍,下面我就怎么设置xml进行说明: 在xml文件的开始几行一般有编写xml文件的语法要求;如 <!DOCTYPE hibernate-con ...
- 关于池化(pooling)理解!!!
网上看到一个池化的解释是: 为了描述大的图像,可以对不同位置的特征进行聚合统计,如计算平均值或者是最大值,即mean-pooling和max-pooling 我的想法是,图像做卷积以后,将图像信息(特 ...
- centos 7.4安装教程
1. 2. 3. 4. 5. 6. 7. 8.
- 微信小程序 在canvas画布上划动,页面禁止滑动
要实现微信小程序 在canvas画布上划动,页面禁止滑动,不仅要设置disable-scroll="true",还要要给canvas绑定一个触摸事件才能生效. <canvas ...
- 针对SO交期回写的工厂日历功能调整
针对所有SO回写的交期,在最终写入SAP系统时,如果交期落在周日的,则自动往后延迟一天到周一,前期已经开发的长节假日UI维护的功能不变(按照UI的开始和结束时间跳过此段时间不规划). 当加1天时落在国 ...
- 材料订单不在IN_MO或者IN_SCFHEADER中
select * from in_sfcheader where MO_ID IN('001600044481'); SELECT * FROM in_sfcheader_temp where MO_ ...