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)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...
随机推荐
- Java解决小孩围圈问题
问题描述:一堆小孩围成一个圈,从第一个小孩开始数,每数到第三个便把第三个孩子删去,数到只剩一个小孩为止,并求该孩子的具体编号. 解决办法 1. package test; public class C ...
- asp.net4.0
asp.net4.0安装路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i
- @JsonInclude注解,RestTemplate传输值为null的属性,利用FastJson将属性中有空值null的对象转化成Json字符串
一个pojo类: import lombok.Data; @Data public class Friend { private String name; private int age; priva ...
- 微信小程序实现滚动分页加载更多
参考网址:https://www.cnblogs.com/Smiled/p/8203306.html 1.wxml: <view class='myScroll' style='float:le ...
- JDBC的基本概念
英文名:Java DataBase Connectivity 中文名:数据库连接 作用: java操作数据库 本质上(sun公司的程序员)定义的一套操作关系型数据库的规则也就是接口,各数据库厂商实现接 ...
- JDBC连接各种数据库的方法,连接MySql,Oracle数据库
JDBC连接各种数据库的方法: JDBC编程步骤: 1.导入jar包 2.注册驱动 3.获取数据库连接对象 4.定义SQL语句 5.获得执行SQL语句对象statemnet 6.执行SQL语句 7.处 ...
- 关于解决java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoader问题
解决方案: 其实是你的jar文件没有同步发布到自己项目的lib目录中 (如果是用Maven进行构建的话) 可以试试 下面的办法 –rebuild下project就可以了 项目点击右键 点击 Prope ...
- selector的例子
例子1 文件名:sl_rounded_rectangle_button_picture.xml 文件内容: <?xml version="1.0" encoding=&quo ...
- sqlserver自增主键
参考 https://www.cnblogs.com/michellexiaoqi/p/8031294.html 1.选中表: 2.右击鼠标,设计: 3.选中列(整数类 ...
- js保留小数点后面几位的方法
原文地址: http://www.jb51.net/article/45884.htm 四舍五入以下处理结果会四舍五入: ? 1 2 var num =2.446242342; num = num.t ...