不妨试试下面这个链接的方法
转自
http://www.cnblogs.com/criedshy/archive/2010/06/13/1757826.htmlC#内存映射文件代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace TestOpenFileMap
{
public class FileMap
{
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
public uint dwOemId;
public uint dwPageSize;
public uint lpMinimumApplicationAddress;
public uint lpMaximumApplicationAddress;
public uint dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public uint dwProcessorLevel;
public uint dwProcessorRevision;
}
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE =0x40000000;
private const int OPEN_EXISTING = 3;
private const int INVALID_HANDLE_VALUE = -1;
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
private const uint PAGE_READWRITE = 0x04;
private const int FILE_MAP_COPY = 1;
private const int FILE_MAP_WRITE = 2;
private const int FILE_MAP_READ = 4;
/// <summary>
/// 内存映射文件句柄
/// </summary>
/// <param name="hFile"></param>
/// <param name="lpFileMappingAttributes"></param>
/// <param name="flProtect"></param>
/// <param name="dwMaximumSizeHigh"></param>
/// <param name="dwMaximumSizeLow"></param>
/// <param name="lpName"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
internal static extern IntPtr CreateFileMapping(IntPtr hFile,
IntPtr lpFileMappingAttributes, uint flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow, string lpName);
/// <summary>
/// 内存映射文件
/// </summary>
/// <param name="hFileMappingObject"></param>
/// <param name="dwDesiredAccess"></param>
/// <param name="dwFileOffsetHigh"></param>
/// <param name="dwFileOffsetLow"></param>
/// <param name="dwNumberOfBytesToMap"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
/// <summary>
/// 撤消文件映像
/// </summary>
/// <param name="lpBaseAddress"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
/// <summary>
/// 关闭内核对象句柄
/// </summary>
/// <param name="hObject"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
internal static extern bool CloseHandle(IntPtr hObject);
/// <summary>
/// 打开要映射的文件
/// </summary>
/// <param name="lpFileName"></param>
/// <param name="dwDesiredAccess"></param>
/// <param name="dwShareMode"></param>
/// <param name="securityAttrs"></param>
/// <param name="dwCreationDisposition"></param>
/// <param name="dwFlagsAndAttributes"></param>
/// <param name="hTemplateFile"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
internal static extern IntPtr CreateFile(string lpFileName,
uint dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs,
FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
/// <summary>
/// 得到文件大小
/// </summary>
/// <param name="hFile"></param>
/// <param name="highSize"></param>
/// <returns></returns>
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern uint GetFileSize(IntPtr hFile, out uint highSize);
/// <summary>
/// 得到系统信息
/// </summary>
/// <param name="lpSystemInfo"></param>
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
/// <summary>
/// 使用内存文件映射得到文件内容
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public StringBuilder GetFileContent(string path)
{
StringBuilder sb = new StringBuilder();
IntPtr fileHandle = CreateFile(path,
GENERIC_READ | GENERIC_WRITE, FileShare.Read | FileShare.Write,
IntPtr.Zero, FileMode.Open,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, IntPtr.Zero);
if (INVALID_HANDLE_VALUE != (int)fileHandle)
{
IntPtr mappingFileHandle = CreateFileMapping(
fileHandle, IntPtr.Zero, PAGE_READWRITE, 0, 0, "~MappingTemp");
if (mappingFileHandle != IntPtr.Zero)
{
SYSTEM_INFO systemInfo = new SYSTEM_INFO(); ;
GetSystemInfo(ref systemInfo);
//得到系统页分配粒度
uint allocationGranularity = systemInfo.dwAllocationGranularity;
uint fileSizeHigh=0;
//get file size
uint fileSize = GetFileSize(fileHandle, out fileSizeHigh);
fileSize |= (((uint)fileSizeHigh) << 32);
//关闭文件句柄
CloseHandle(fileHandle);
uint fileOffset = 0;
uint blockBytes = 1000 * allocationGranularity;
if (fileSize < 1000 * allocationGranularity)
blockBytes = fileSize;
//分块读取内存,适用于几G的文件
while (fileSize > 0)
{
// 映射视图,得到地址
IntPtr lpbMapAddress = MapViewOfFile(mappingFileHandle, FILE_MAP_COPY | FILE_MAP_READ | FILE_MAP_WRITE,
(uint)(fileOffset >> 32), (uint)(fileOffset & 0xFFFFFFFF),
blockBytes);
if (lpbMapAddress == IntPtr.Zero)
{
return sb;
}
// 对映射的视图进行访问
byte[] temp = new byte[blockBytes];
//从非托管的内存中复制内容到托管的内存中
Marshal.Copy(lpbMapAddress, temp, 0, (int)blockBytes);
//用循环太慢了,文件有几M的时候就慢的要死,还是用上面的方法直接
//for (uint i = 0; i < dwBlockBytes; i++)
//{
// byte vTemp = Marshal.ReadByte((IntPtr)((int)lpbMapAddress + i));
// temp[i] = vTemp;
//}
//此时用ASCII解码比较快,但有中文会有乱码,用gb2312即ANSI编码也比较快,16M的文件大概4秒就读出来了
//但用unicode解码,文件大的时候会非常慢,会现卡死的状态,不知道为什么?
//ASCIIEncoding encoding = new ASCIIEncoding();
//System.Text.UnicodeEncoding encoding = new UnicodeEncoding();
//sb.Append(encoding.GetString(temp));
sb.Append(System.Text.Encoding.GetEncoding("gb2312").GetString(temp));
// 撤消文件映像
UnmapViewOfFile(lpbMapAddress);
// 修正参数
fileOffset += blockBytes;
fileSize -= blockBytes;
}
//close file mapping handle
CloseHandle(mappingFileHandle);
}
}
return sb;
}
}
}