分享

统计一个大文本行数的几种方法以及效率统计(二)

 ruiruiruiruichen 2013-08-28



.NET4.0 + MemoryMapping + ReadByte()


该方法的思路主要是通过内存映射的原理,访问文件内容,由于在.net环境下不能一次性映射太大的文件,所以仍然采用分块映射的方式:


主要代码如下:


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);
    }
}

测试结果:


MemoryMapping ReadByte()


.NET4.0 + MemoryMapping + Unsafe


使用unsafe代码,就是在上面代码的基础上,做了一些简单的修改。


 


1
2
byte* pbHead = (byte*)pHead;
byte temp = *(pbHead + flag);

1
  

测试结果:


MemoryMapping Unsafe

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多