C#大文件读取和查询--内存映射
笔者最近需要快速查询日志文件,文件大小在4G以上。
需求如下:
1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M。
2.希望查询1G以内容,能控制在20s左右.
刚开始觉得这个应该不难.研究一天之后,发现这个需要使用内存映射技术。
查阅了相关资料之后
发现还是有一定的复杂性.特别是需要对字符处理。
笔者自己写了一个Demo,希望实现
很遗憾,测试结果,查询1G左右的内容,花费时间在100s左右.
程序如下:
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Text; namespace ConsoleDemo
{
class Program
{
private const string TXT_FILE_PATH = @"E:\开源学习\超大文本文件读取\File\a.txt";
private const string SPLIT_VARCHAR = "囧";
private const char SPLIT_CHAR = '囧';
private static long FILE_SIZE = ;
static void Main(string[] args)
{
//long ttargetRowNum = 39999999;
long ttargetRowNum = ;
DateTime beginTime = DateTime.Now;
string line = CreateMemoryMapFile(ttargetRowNum);
double totalSeconds = DateTime.Now.Subtract(beginTime).TotalSeconds;
Console.WriteLine(line);
Console.WriteLine(string.Format("查找第{0}行,共耗时:{1}s", ttargetRowNum, totalSeconds));
Console.ReadLine();
} /// <summary>
/// 创建内存映射文件
/// </summary>
private static string CreateMemoryMapFile(long ttargetRowNum)
{
string line = string.Empty;
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);
if (curRowNum <= targetRowNum)
{
if (curRowNum < targetRowNum)
{
string s = sbDefineRowLine.ToString();
int pos = s.LastIndexOf(SPLIT_CHAR);
if (pos > )
sbDefineRowLine.Remove(, pos); }
else
{
line = sbDefineRowLine.ToString();
return line;
}
if (ss.Contains(SPLIT_VARCHAR))
{
curRowNum += GetNewLineNumsOfStr(ss);
sbDefineRowLine.Append(ss);
}
else
{
sbDefineRowLine.Append(ss);
}
}
//sbDefineRowLine.Append(ss);
//line = sbDefineRowLine.ToString();
//if (ss.Contains(Environment.NewLine))
//{
// ++curRowNum;
// //curRowNum++;
// //curRowNum += GetNewLineNumsOfStr(ss);
// //sbDefineRowLine.Append(ss);
//}
//if (curRowNum == targetRowNum)
//{
// string s = "";
//} sr.Dispose();
} mmStream.Dispose();
}
} while (offset < fs.Length);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return line;
}
}
} private static long GetNewLineNumsOfStr(string s)
{
string[] _lst = s.Split(SPLIT_CHAR);
return _lst.Length - ;
}
}
}
测试截图:

欢迎大家提供更好的解决思路.
参考资料:
https://msdn.microsoft.com/zh-cn/library/dd997372(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
http://blog.csdn.net/onejune2013/article/details/7577152
C#大文件读取和查询--内存映射的更多相关文章
- 【转】C#大文件读取和查询--内存映射
笔者最近需要快速查询日志文件,文件大小在4G以上. 需求如下: 1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M. 2.希望查询1G以内容,能控制在20s左右. 刚开始觉得这个应该 ...
- Java解决大文件读取的内存问题以及文件流的比较
Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...
- linux大文件读取
在生产环境中有时候可能会遇到大文件的读取问题,但是大文件读取如果按照一般的手法.如cat这种都是对io的一个挑战,如果io扛得住还好,如果扛不住 造成的后果,如服务器内存奔溃,日志损坏 方法一: se ...
- PHP大文件读取操作
简单的文件读取,一般我们会使用 file_get_contents() 这类方式来直接获取文件的内容.不过这种函数有个严重的问题是它会把文件一次性地加载到内存中,也就是说,它会受到内存的限制.因此,加 ...
- python大文件读取
python大文件读取 https://stackoverflow.com/questions/8009882/how-to-read-a-large-file-line-by-line-in-pyt ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- Python读取大文件的"坑“与内存占用检测
python读写文件的api都很简单,一不留神就容易踩"坑".笔者记录一次踩坑历程,并且给了一些总结,希望到大家在使用python的过程之中,能够避免一些可能产生隐患的代码. 1. ...
- java 导出 excel 最佳实践,java 大文件 excel 避免OOM(内存溢出) excel 工具框架
产品需求 产品经理需要导出一个页面的所有的信息到 EXCEL 文件. 需求分析 对于 excel 导出,是一个很常见的需求. 最常见的解决方案就是使用 poi 直接同步导出一个 excel 文件. 客 ...
- 大文件读取方法(C#)
之前都是用StreamReader.ReadLine方法逐行读取文件,自从.NET4有了File.ReadLines这一利器,就再也不用为大文件发愁了. File.ReadLines在整个文件读取到内 ...
随机推荐
- 【JavaScript兼容】关于IE8及以下无法通过getElementsByClassName()方法获得元素的解决方法
try{ var a = document.getElementsByClassName("cla"); console.log(a); }catch(ex){ var array ...
- 关于如何通过定义自己的CameraManager来控制视角
2016.8.30 发现了这个函数,可以直接获得摄像机的位置和旋转. Controller->GetPlayerViewPoint(CamLoc, CamRot); 最近看了几天PlayerCa ...
- [深入浅出WP8.1(Runtime)]Windows Phone 8.1和Silverlight 8.1的区别
1.2.2 Windows Phone 8.1应用程序模型 Windows Phone 8.1支持多种开发语言来开发应用程序,包括C#.VB.JavaScript和C++,那么本书的代码主要是采用C# ...
- IOS_ios逆向工程-静态分析
返回博客列表 原 ios逆向工程-静态分析 余成海 发布时间: 2014/11/03 19:17 阅读: 11201 收藏: 17 点赞: 5 评论: 6 最近在学习IOS逆向工程,查看网络上的资料也 ...
- gVim的pathogen
1.安装gVim 1.选择Full模式 2. 在vimfiles 文件夹下,会有许多空文件夹.将它们全删掉. 3.将vim74文件夹下的"autoload"文件夹 剪切 到 vim ...
- stl文件格式
http://wenku.baidu.com/view/a3ab7a26ee06eff9aef8077b.html [每个三角形面片的定义包括三角形各个定点的三维坐标及三角形面片的法矢量[三角形的法线 ...
- iOS CoreAnimation 核心动画
一 介绍 一组非常强大的动画处理API 直接作用在CALAyer上,并非UIView(UIView动画) CoreAnimation是所有动画的父类,但是不能直接使用,应该使用其子类 属性: dura ...
- NOIP2014初赛分数线及金华上线名单
NOIP2014初赛分数线及金华上线名单 分数线:提高组81.5,普及组93 这分数线还能再高些吗?悲催的浙江. 金华上线普及组名单: 地市 姓名 学校 年级 参赛语种 成绩 金华 成浩鹏 稠州丹溪校 ...
- 中國區的代理協議的韓國遊戲廠商PatiGames
“與阿裏巴巴簽署旗下游戲「突突三國」在中國區的代理協議的韓國遊戲廠商PatiGames決定與阿裏巴巴終止合作.”相信這條前不久報導的新聞,很多人並不陌生,但這背後其實並不像表面那樣簡單.早在今年4月P ...
- # 20145205 《Java程序设计》第1周学习总结
教材学习内容总结 第一章中 JAVA的三大体系:JAVA SE .JAVA EE.JAVA ME.而在其中书中主要介绍我们入门学习者所要学习的JVAA SE,其又可分为四个主要组成部分同Java SE ...