如题目所示:C#中如何创建文件?如何创建内存映射文件并保持内存映射文件同硬盘文件的同步?
即,我创建了一个硬盘文件之后,我把这个硬盘文件中的内容映射到内存中。
我在不同的线程中操作这个内存,读/写这块内存。后台自动将内存中的内容保存到文件中。请各位兄弟姐妹指教。

解决方案 »

  1.   

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;namespace ShareMemLib
    {
        public class ShareMem
        {
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
            
            [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr OpenFileMapping(int dwDesiredAccess,[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,string lpName);        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr MapViewOfFile(IntPtr hFileMapping,uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,uint dwNumberOfBytesToMap);        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern bool CloseHandle(IntPtr handle);        [DllImport("kernel32", EntryPoint="GetLastError")]
            public static extern int GetLastError ();        const int ERROR_ALREADY_EXISTS = 183;        const int FILE_MAP_COPY = 0x0001;
            const int FILE_MAP_WRITE = 0x0002;
            const int FILE_MAP_READ = 0x0004;
            const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;        const int PAGE_READONLY = 0x02;
            const int PAGE_READWRITE = 0x04;
            const int PAGE_WRITECOPY = 0x08;
            const int PAGE_EXECUTE = 0x10;
            const int PAGE_EXECUTE_READ = 0x20;
            const int PAGE_EXECUTE_READWRITE = 0x40;        const int SEC_COMMIT = 0x8000000;
            const int SEC_IMAGE = 0x1000000;
            const int SEC_NOCACHE = 0x10000000;
            const int SEC_RESERVE = 0x4000000;        const int INVALID_HANDLE_VALUE = -1;        IntPtr m_hSharedMemoryFile = IntPtr.Zero;
            IntPtr m_pwData = IntPtr.Zero;
            bool m_bAlreadyExist = false;
            bool m_bInit = false;
            long m_MemSize=0;        public ShareMem()
            {
            }
            ~ShareMem()
            {
                Close();
            }        /// <summary>
            /// 初始化共享内存
            /// </summary>
            /// <param name="strName">共享内存名称</param>
            /// <param name="lngSize">共享内存大小</param>
            /// <returns></returns>
            public int Init(string strName, long lngSize)
            {
                if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
                m_MemSize = lngSize;
                if (strName.Length > 0)
                {
                    //创建内存共享体(INVALID_HANDLE_VALUE)
                    m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
                    if (m_hSharedMemoryFile == IntPtr.Zero)
                    {
                        m_bAlreadyExist = false;
                        m_bInit = false;
                        return 2; //创建共享体失败
                    }
                    else
                    {
                        if (GetLastError() == ERROR_ALREADY_EXISTS)  //已经创建
                        {
                            m_bAlreadyExist = true;
                        }
                        else                                         //新创建
                        {
                            m_bAlreadyExist = false;
                        }
                    }
                    //---------------------------------------
                    //创建内存映射
                    m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_WRITE, 0, 0, (uint)lngSize);
                    if (m_pwData == IntPtr.Zero)
                    {
                        m_bInit = false;
                        CloseHandle(m_hSharedMemoryFile);
                        return 3; //创建内存映射失败
                    }
                    else
                    {
                        m_bInit = true;
                        if (m_bAlreadyExist == false)
                        {
                            //初始化
                        }
                    }
                    //----------------------------------------
                }
                else
                {
                    return 1; //参数错误     
                }            return 0;     //创建成功
            }
            /// <summary>
            /// 关闭共享内存
            /// </summary>
            public void Close()
            {
                if (m_bInit)
                {
                    UnmapViewOfFile(m_pwData);
                    CloseHandle(m_hSharedMemoryFile);
                }
            }        /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="bytData">数据</param>
            /// <param name="lngAddr">起始地址</param>
            /// <param name="lngSize">个数</param>
            /// <returns></returns>
            public int Read(ref byte[] bytData, int lngAddr, int lngSize)
            {
                if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
                if (m_bInit)
                {               
                    Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
                }
                else
                {
                    return 1; //共享内存未初始化
                }
                return 0;     //读成功
            }        /// <summary>
            /// 写数据
            /// </summary>
            /// <param name="bytData">数据</param>
            /// <param name="lngAddr">起始地址</param>
            /// <param name="lngSize">个数</param>
            /// <returns></returns>
            public int Write(byte[] bytData, int lngAddr, int lngSize)
            {
                if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
                if (m_bInit)
                {
                    Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
                }
                else
                {
                    return 1; //共享内存未初始化
                }
                return 0;     //写成功
            }
        }
    }
      

  2.   

    ShareMem MemDB=new ShareMem();
    MemDB.Init("Test", 10240);//不同程序用一个共享内存 ,名字要一样
     MemDB.Write(data[], 0, data.length);
      

  3.   

    C#是托管的环境,而FileMapping用非托管的内存。如果你只是在不同的线程中操作,不是在多个进程中操作,建议不用FileMapping。如果你对IntPtr信心很足的话,你可以试试用这些APIs:CloseHandle
    CreateFileMapping
    MapViewOfFile
    WriteFile
      

  4.   

    请问Kamui(湿他就湿他):这样创建的内存映像文件,是否需要我手动去将内存中的内容保存到硬盘文件中?
    API会不会帮我后台自动保存?
      

  5.   

    不需要
    你要是保存成文件的话
    直接用FileStrem保存内存中的数据就可以了。
    MemDB.Read(data[],0,data.lenth);
    FileStream.Writer(data,0,data.lenth);
      

  6.   

    那就是说我还得调用语句:
    MemDB.Read(data[],0,data.lenth); 
    FileStream.Writer(data,0,data.lenth);
    将内存中的数据保存到文件中了。我的意思是在使用前面那些API创建内存映射文件的时候,
    是否有某个参数可以指定我在操作文件的时候,另外有个后台线程在帮我把内存中的数据自动保存到文件中?
    就像Microsoft Word软件中的自动保存一样。
      

  7.   

    请问Kamui(湿他就湿他):帮小弟解答一下下面的问题:那就是说我还得调用语句: 
    MemDB.Read(data[],0,data.lenth);  
    FileStream.Writer(data,0,data.lenth); 
    将内存中的数据保存到文件中了。 我的意思是在使用前面那些API创建内存映射文件的时候, 
    是否有某个参数可以指定我在操作文件的时候,另外有个后台线程在帮我把内存中的数据自动保存到文件中? 
    就像Microsoft Word软件中的自动保存一样。
      

  8.   

    请问Kamui(湿他就湿他):初始化内存共享体之后,硬盘文件中的数据加载到内存共享体之中的过程,是否还需要我调用某些函数来实现?
    是否此时已经自动加载到内存中了?如果此时硬盘文件中的数据没有自动加载到内存共享体中,是否需要打开硬盘文件,将文件中的内容读入内存共享体中?谢谢!