1. 程式人生 > >記憶體操作類(共享對映檔案 MemoryMappedFile)

記憶體操作類(共享對映檔案 MemoryMappedFile)

需要完善的地方:

一個記憶體物件佔地1G,資源浪費太嚴重。動態大小更合理,每次重新建立有可能多個程序之間衝突。

IIS和winform之間存在應用許可權隔離,並且iis本身許可權較低,涉及系統操作會被拒絕,提權有隱患。

場景有限,效率感人,僅供參考,redis大法好。

    /// <summary>
    /// 首4個位元組為檔案長度,該類存對應記憶體區域所存放的資料不能超過1G。記憶體區域不是私有獨佔物件。
    /// </summary>
    class memobj
    {
        MemoryMappedFile mmf;
        MemoryMappedViewStream mmvs;
        string name;
        uint maxlen = (1<<30) + 4;


        /// <summary>
        /// 建立一個memobj物件,獲取/建立name屬性對應的記憶體對映檔案,並寫入內容。如果檔案已存在,將覆蓋。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <param name="name">memobj物件名稱,私有</param>
        /// <param name="content">寫入記憶體的內容</param>
        public memobj(string name,byte[] content)
        {
            this.name = name;
            mmf = MemoryMappedFile.CreateOrOpen(name, maxlen, MemoryMappedFileAccess.ReadWrite);
            mmvs = mmf.CreateViewStream();
            if (content.Length >= maxlen)
            {
                throw new OutOfMemoryException();
            }
            else
            {
                WriteContent(content);
            }
        }


        /// <summary>
        /// 建立一個memobj物件,獲取/建立name屬性對應的記憶體對映檔案。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <param name="name">memobj物件名稱</param>
        public memobj(string name)
        {
            this.name = name;
            mmf = MemoryMappedFile.CreateOrOpen(name, maxlen, MemoryMappedFileAccess.ReadWrite);
            mmvs = mmf.CreateViewStream();
        }


        /// <summary>
        /// 將資料長度寫入記憶體區域的首4位元組。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <param name="Length"></param>
        private void WriteLength(uint Length)
        {
            byte[] ret = new byte[4];
            ret[0] = Convert.ToByte((Length >> 24) % 256);
            ret[1] = Convert.ToByte((Length >> 16) % 256);
            ret[2] = Convert.ToByte((Length >> 8) % 256);
            ret[3] = Convert.ToByte(Length   % 256);
            mmvs.Position = 0;
            mmvs.Write(ret, 0, 4);
        }


        /// <summary>
        /// 獲取記憶體資料長度,通過前4個位元組計算,不存在Length屬性。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <returns></returns>
        public int Length()
        {
            mmvs.Position = 0;
            byte[] ret = new byte[4];
            mmvs.Read(ret, 0, 4);
            return (ret[0] << 24) + (ret[1] << 16) + (ret[2]<<8) + ret[3];
        }


        /// <summary>
        /// 寫入資料長度到記憶體區域首4位元組。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <param name="content"></param>
        public void WriteContent(byte[] content)
        {
            mmvs.Position = 0;
            WriteLength((uint)content.Length);
            mmvs.Write(content, 0, content.Length);
        }


        /// <summary>
        /// 從記憶體區域首4位元組計算資料長度並讀出記憶體資料。記憶體區域不是私有獨佔物件。
        /// </summary>
        /// <returns></returns>
        public byte[] Read()
        {
            int bytLength = Length();
            byte[] ret = new byte[bytLength];
            mmvs.Position = 4;
            mmvs.Read(ret, 0, bytLength);
            return ret;
        }
    }