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)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...
随机推荐
- jQuery图片延迟加载插件:jquery.lazyload
----------------------------------------------------------------------------------------------- clas ...
- Python异常和调试.md
异常捕获 try 基本概念 我们使用try except来捕获异常,python的try except有几个特点: 不管函数内部嵌套几层,只要在try的范围内就可以被捕获.这句话的意思是一个函数被tr ...
- WebAPI 和 webservice接口
1. webservice走HTTP协议和80端口.WebService则类似于bs架构,只需要开发服务器端,不需要开发客户端,客户端只要遵循soap协议,就可以调用. 2. api,用的协议和端口, ...
- 04_web基础(九)考核与评估
- 1.3.2、CDH 搭建Hadoop在安装之前(端口---Cloudera Navigator加密使用的端口)
列出的所有端口都是TCP. 在下表中,每个端口的“ 访问要求”列通常是“内部”或“外部”.在此上下文中,“内部”表示端口仅用于组件之间的通信; “外部”表示该端口可用于内部或外部通信. 零件 服务 港 ...
- Debug模块
[Debug模块] 一个用于控制日志输出的模块. 参考: 1.http://www.jianshu.com/p/6b9833748f36 2.https://www.npmjs.com/package ...
- 安装beanstalkd
运行下面命令安装: yum install epel-releaseyum -y install beanstalkd --enablerepo=epel
- metasploit framework(三):exploit模块
exploit模块 分为主动,被动exploit 主动exploit:攻击者(通常是客户端)主动发起连接请求,然后发送exploit给被攻击者(通常是服务器端) 被动exploit:被攻击者(通常是客 ...
- Unable to compile class for JSP
https://www.cnblogs.com/mthoutai/p/7136304.html 错误提示: The return type is incompatible with JspSource ...
- openjdk1.8 源码地址
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/656ab3b39178/src/