Bekerja dengan fail yang dipetakan memori di .Net

Akses fail adalah operasi intensif sumber. Mengakses fail dari disk untuk aplikasi adalah operasi yang memakan waktu, dan mengakses data dari memori utama selalu lebih cepat. Jadi, bagaimana jika fail cakera yang perlu dibaca atau ditulis oleh aplikasi anda berada dalam ingatan? Di sinilah konsep fail pemetaan memori sesuai. Dalam artikel ini, kita akan meneroka bagaimana kita dapat bekerja dengan fail yang dipetakan memori di .Net.

Memperkenalkan fail yang dipetakan memori

File yang dipetakan memori adalah objek kernel yang digunakan untuk memetakan file dalam disk anda ke wilayah di memori utama. Fail yang dipetakan memori dapat memperoleh peningkatan prestasi yang besar berbanding dengan akses cakera langsung ketika bekerja dengan sejumlah besar data atau gambar besar. Fail yang dipetakan memori telah menjadi sebahagian dari Win32 API, tetapi sehingga baru-baru ini, anda dibatasi untuk menggunakan C ++ atau PInvoke untuk menulis kod yang memanfaatkan fail yang dipetakan memori dalam aplikasi anda. Walau bagaimanapun dengan .Net Framework 4, anda kini dapat bekerja dengan fail yang dipetakan memori terus dari aplikasi .Net anda - runtime sekarang menyediakan anda pembungkus teratur dengan semua kelas pembungkus yang diperlukan untuk memanggil Win32 API. MSDN menyatakan: "Fail yang dipetakan memori berisi isi file dalam memori maya. Pemetaan antara fail dan ruang memori memungkinkan aplikasi, termasuk beberapa proses,untuk mengubah suai fail dengan membaca dan menulis terus ke memori. "

Mengapa anda memerlukan fail yang dipetakan memori?

Fail yang dipetakan memori adalah pilihan yang baik apabila anda perlu bekerja dengan sejumlah besar data dan anda ingin mengelakkan kos yang berkaitan dengan marshaling dan un-marshaling semasa berkongsi data melintasi batas proses. Fail yang dipetakan memori sangat bagus dalam memproses fail besar - membaca fail besar adalah operasi sumber yang luas. Dengan fail yang dipetakan memori, anda dapat memetakan bahagian tertentu dari fail anda ke dalam memori dan melakukan operasi I / O dengan blok tersebut untuk mempercepat akses.

Fail yang dipetakan memori membolehkan anda menempah pelbagai alamat memori dan menggunakan fail cakera sebagai simpanan fizikal untuk alamat yang dikhaskan. Dengan kata lain, ia membolehkan anda menempah ruang dalam memori dan kemudian melakukan penyimpanan fizikal ke rantau itu. Ini membolehkan anda mengakses data pada cakera tanpa perlu melakukan operasi I / O fail. Fail yang dipetakan memori juga membolehkan anda berkongsi data melalui pelbagai proses. Sistem Operasi mengurus pengurusan memori untuk fail yang dipetakan memori - anda tidak perlu peduli bagaimana fail tersebut dipartisi ke dalam halaman dan diuruskan. Anda juga dapat menerapkan keamanan dalam file yang dipetakan memori dengan menggunakan enumerasi MemoryMappedFileAccess sebagai parameter ketika membuat file yang dipetakan memori. 

Fail yang dipetakan memori berterusan dan tidak berterusan

Pada asasnya terdapat dua jenis fail yang dipetakan memori. Ini adalah:

Berterusan : Fail yang dipetakan memori berterusan adalah fail yang dikaitkan dengan fail sumber dalam cakera dalam sistem anda. Apabila anda bekerja dengan jenis fail yang dipetakan memori ini, data akan disimpan dalam cakera setelah proses terakhir yang dilakukan pada fail menyelesaikan aktivitinya.

Tidak berterusan : Fail yang dipetakan memori tidak berterusan adalah fail yang tidak dikaitkan dengan fail cakera. Apabila anda bekerja dengan jenis fail yang dipetakan memori ini, data tidak akan berterusan setelah proses terakhir yang dilakukan pada fail tersebut selesai berfungsi. Fail pemetaan memori tidak berterusan sangat bagus dalam berkongsi memori untuk komunikasi antara proses.

Membuat fail yang dipetakan memori berterusan

Untuk membuat fail pemetaan memori berterusan, anda perlu menggunakan kaedah CreateFromFile dari kelas MemoryMappedFile. Kelas MemorymappedFile hadir di ruang nama System.IO.MemoryMappedFiles.

Coretan kod berikut menggunakan kaedah CreateFromFile untuk membuat fail yang dipetakan memori. Seterusnya menghasilkan paparan memori ke sebahagian fail.

static long offset = 0x10000000; // 256 megabytes

static long length = 0x20000000; // 512 megabytes

        static void Main()

        {

            using (var memoryMappedFile = MemoryMappedFile.CreateFromFile("F:\\ImageData.png", FileMode.Open, "PartitionA"))

            {

                using (var accessor = memoryMappedFile.CreateViewAccessor(offset, length))

                {

                    //Other code

                }

            }

        } 

Coretan kod yang diberikan seterusnya menunjukkan bagaimana anda dapat membaca data dari fail yang dipetakan memori.

using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile("F:\\LargeData.dat"))

            {

                using (MemoryMappedViewStream memoryMappedViewStream = memoryMappedFile.CreateViewStream(0, 1204, MemoryMappedFileAccess.Read))

                {

                    var contentArray = new byte[1024];

                    memoryMappedViewStream.Read(contentArray, 0, contentArray.Length);

                    string content = Encoding.UTF8.GetString(contentArray);

                }

            }

Membuat fail yang dipetakan memori tidak berterusan

Untuk membuat fail yang dipetakan memori tidak berterusan, iaitu, file yang tidak dipetakan ke file yang ada pada disk, anda perlu memanfaatkan kaedah CreateNew dan CreateOrOpen.

Coretan kod berikut menggambarkan bagaimana fail yang dipetakan memori tidak berterusan dapat dibuat.

using(MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateNew("idg.txt", 5))

            {

                using(MemoryMappedViewAccessor memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())

                {

                var data = new[] { (byte)'I', (byte)'D', (byte)'G'};

                for (int i = 0; i < data.Length; i++)

                    memoryMappedViewAccessor.Write(i, data[i]);

                memoryMappedViewAccessor.Dispose();

                memoryMappedFile.Dispose();

                }

            }

Anda boleh mengetahui lebih lanjut mengenai fail yang dipetakan memori dari artikel MSDN ini.