該方法的思路主要是通過內(nèi)存映射的原理,訪問文件內(nèi)容,由于在.net環(huán)境下不能一次性映射太大的文件,所以仍然采用分塊映射的方式:
主要代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /// <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); } } |
測(cè)試結(jié)果:
使用unsafe代碼,就是在上面代碼的基礎(chǔ)上,做了一些簡(jiǎn)單的修改。
測(cè)試結(jié)果:
聯(lián)系客服