.NET4.0 + MemoryMapping + ReadByte()
该方法的思路主要是通过内存映射的原理,访问文件内容,由于在.net环境下不能一次性映射太大的文件,所以仍然采用分块映射的方式:
主要代码如下:
/// <summary>
/// MemoryMapping + ReadByte()
/// </summary>
unsafe static void CalulateLine_MemoryMapping_ReadByte(uint oneBlockSize)
{
const string FILE_MAPPING_NAME = "~MappingTemp";
const int LINE_MIN_SIZE = 30;
long lineCount = 0;
IntPtr fileHandle = ShareMemory.CreateFile(
FILE_NAME,
ShareMemory.GENERIC_READ | ShareMemory.GENERIC_WRITE,
FileShare.Read | FileShare.Write,
IntPtr.Zero,
FileMode.Open,
ShareMemory.FILE_ATTRIBUTE_NORMAL | ShareMemory.FILE_FLAG_SEQUENTIAL_SCAN,
IntPtr.Zero);
uint fileSize = ShareMemory.GetFileSize(fileHandle, IntPtr.Zero);
if (ShareMemory.INVALID_HANDLE_VALUE != (int)fileHandle)
{
IntPtr mappingHandle = ShareMemory.CreateFileMapping(
(int)fileHandle,
IntPtr.Zero,
ShareMemory.PAGE_READWRITE,
0,
0,
FILE_MAPPING_NAME);
if (mappingHandle != IntPtr.Zero)
{
uint mapFlag = 0;
while (mapFlag <= fileSize)
{
uint eachMappingSize = oneBlockSize;
if (fileSize - mapFlag < oneBlockSize)
{
eachMappingSize = fileSize - mapFlag;
}
IntPtr pHead = ShareMemory.MapViewOfFile(
mappingHandle,
(uint)(ShareMemory.FILE_MAP_READ),
0,
mapFlag,
eachMappingSize);
int lastError = ShareMemory.GetLastError();
if (pHead != IntPtr.Zero)
{
long flag = 0;
while (flag < eachMappingSize)
{
//byte* pbHead= (byte*)pHead;
//byte temp = *(pbHead + flag);
byte temp = Marshal.ReadByte((IntPtr)((int)pHead + flag));
if (temp == 0x0D)
{
lineCount++;
flag += LINE_MIN_SIZE;
}
flag++;
}
ShareMemory.UnmapViewOfFile(pHead);
}
mapFlag += oneBlockSize;
}
ShareMemory.CloseHandle(mappingHandle);
}
ShareMemory.CloseHandle(fileHandle);
}
}
测试结果:
.NET4.0 + MemoryMapping + Unsafe
使用unsafe代码,就是在上面代码的基础上,做了一些简单的修改。
byte* pbHead = (byte*)pHead; byte temp = *(pbHead + flag);
测试结果:



浙公网安备 33010602011771号