using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Text;
namespace app1
{ class Program
{
private const string DAT_FILE_PATH = @"F:test.dat";
private const string SPLIT_VARCHAR = "";
private const char SPLIT_CHAR = '';
private static long FILE_SIZE = 0;
static void Main(string[] args)
{
long ttargetRowNum = 10000000;
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();
}
private static string CreateMemoryMapFile(long ttargetRowNum)
{
string line = string.Empty;
using (FileStream fs = new FileStream(DAT_FILE_PATH, FileMode.Open, FileAccess.ReadWrite))
{
long targetRowNum = ttargetRowNum + 1;//目标行
long curRowNum = 1;//当前行
FILE_SIZE = fs.Length;
using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "test1", fs.Length, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, false))
{
long offset = 0;
int limit = 200;
try
{
StringBuilder sbDefineRowLine = new StringBuilder();
do
{
long remaining = fs.Length - offset;
using (MemoryMappedViewStream mmStream = mmf.CreateViewStream(offset, remaining > limit ? limit : remaining))
{
offset += limit;
using (StreamReader sr = new StreamReader(mmStream))
{
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 > 0)
sbDefineRowLine.Remove(0, pos);
}
else
{
line = sbDefineRowLine.ToString();
return line;
}
if (ss.Contains(SPLIT_VARCHAR))
{
curRowNum += GetNewLineNumsOfStr(ss);
sbDefineRowLine.Append(ss);
}
else
{
sbDefineRowLine.Append(ss);
}
}
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 - 1;
}
}
}