ملفات الذاكرة المُعَنوَنَة

يحتوي ملف الذاكرة المعنونة على محتويات ملف في الذاكرة الظاهرية ومن أحد تطبيقات مساحة العناوين المنطقية. هذا التعيين بين ملف و مسافة يمكن تطبيق ما، بما في ذلك عمليات متعددة، لتعديل الملف عن طريق قراءة ذاكرة و الكتابة مباشرة إلى ذاكرة. بدءاً من .NET Framework الإصدار 4، يمكنك استخدام تعليمات برمجية مُدارة للوصول إلى ملفات ذاكرة المعنونة بنفس الطريقة من وظائف Windows الأصلي الوصول ملفات ذاكرة المعنونة كـ الموصوفة في ملفات Managing ذاكرة-Mapped في Win32 في مكتبة MSDN.

هناك نوعان من ملفات الذاكرة المعنونة:

  • ملفات الذاكرة المعنونة الدائمة

    الملفات الدائمة هي ملفات الذاكرة المعنونة القترنة بملف مصدر على قرص. عند انتهاء العملية الأخيرة من العمل علي الملف، يتم حفظ البيانات إلى ملف المصدر على القرص. تكون ملفات الذاكرة المعنونة مناسبة للعمل علي ملفات المصدر الكبيرة للغاية. يبين الرسم التوضيحي التالي ملفات الذاكرة المعنونة التي تكون موجودة بشكل دائم علي القرص.

  • ملفات الذاكرة المعنونة غير الدائمة

    الملفات غير الدائمة هي ملفات الذاكرة المعنونة غير المقترنة بملف مصدر على قرص. عند انتهاء العملية الأخيرة من العمل علي الملف, يتم فقدان البيانات الموجودة ثم استعادة الملف بواسطة مجموعة البيانات المهملة. هذه الملفات مناسبة لإنشاء ذاكرة مشتركة من أجل اتصالات العمليات الداخلية (IPC). يبين الرسم التوضيحي التالي ملفات الذاكرة المعنونة التي تكون ليست موجودة بشكل دائم علي القرص.

العمليات و طرق عرض و إدارة الذاكرة

يمكن مشاركة ملفات الذاكرة المعنونة عبر عدة عمليات. يمكن للعمليات تعيين نفس ملف الذاكرة المعنونة باستخدام اسم شائع المعين من قبل عملية إنشاء الملف.

للعمل علي ملفات الذاكرة المعنونة، يجب عليك إنشاء عرض لملف الذاكرة المعنونة بأكمله أو جزء منه. يمكنك أيضاً إنشاء ‏‫طرق عرض‬ متعددة لنفس الجزء من ملف الذاكرة المعنونة وبالتالي يتم إنشاء ذاكرة متزامنة. للحصول على طريقتين للعرض لكي تبقى الذاكرة متزامنة، يجب أن يتم إنشاؤها من نفس ملف الذاكرة المعنونة.

طرق عرض متعددة قد يكون ضروريا إذا كان ملف أكبر من الحجم مسافة ذاكرة المنطقية للتطبيق متوفراً للذاكرة بتعيين (2 GB تشغيل جهاز كمبيوتر 32 بت).

وهناك نوعين من ‏‫طرق العرض‬: طريق عرض الوصول الدفق و طريقة عرض الوصول العشوائي. استخدام طرق العرض للوصول إلى دفق للوصول المتسلسل ملف؛ ينصح بهذا الأمر لا يستمر ملف s و IPC. طرق عرض الوصول العشوائي هي المفضلة للعمل علي الملفات الدائمة.

يتم الوصول إلى ملفات الذاكرة المعنونة من خلال نظام التشغيل أو مدير الذاكرة، لكي يتم تلقائياً تقسيم الملف إلى عدد الصفحات التي تم الوصول إليها حسب الحاجة. ليس من الضروري أن تقوم بمعالجة إدارة الذاكرة بنفسك.

يبين المثال التالي يمكن أن يكون لعدد عمليات متعددة وتراكب طرق العرض إلى ملف معين للذاكرة نفسه في نفس الوقت.

متعددة وطرق العرض متراكبة إلى ملف معين للذاكرة

تظهر طرق عرض لملف معين للذاكرة.

برمجة ملفات الذاكرة المعنونة

يوفر الجدول التالي إرشادات لاستخدام كائانات ملفات الذاكرة المعنونة والأعضاء الخاصة بهم.

المهمة

أساليب أو خصائص المستخدمة

للحصول على كائن MemoryMappedFile الذي يمثل ملف الذاكرة المعنونة الدائمة من ملف على القرص.

MemoryMappedFile.CreateFromFileالطريقة الثانية:

للحصول على الكائن MemoryMappedFile الذي يمثل ملف الذاكرة المعنونة غير الدائمة (غير المقترن بملف على القرص).

MemoryMappedFile.CreateNewالطريقة الثانية:

-أو-

MemoryMappedFile.CreateOrOpenالطريقة الثانية:

للحصول على كائن MemoryMappedFile لملف ذاكرة معنونة موجود مسبقاً (دائمة أو غير الدائمة).

MemoryMappedFile.OpenExistingالطريقة الثانية:

للحصول على الكائن UnmanagedMemoryStream لطريقة عرض يتم الوصول إليها بشكل تسلسلي لملف الذاكرة المعنونة.

MemoryMappedFile.CreateViewStreamالطريقة الثانية:

للحصول على الكائن UnmanagedMemoryAccessor لطريقة عرض وصول عشوائي للذاكرة المعنونة fie.

MemoryMappedFile.CreateViewAccessorالطريقة الثانية:

للحصول على الكائن SafeMemoryMappedViewHandle لاستخدام تعليمات برمجية غير مدارة.

الخاصية MemoryMappedFile.SafeMemoryMappedFileHandle

-أو-

الخاصية MemoryMappedViewAccessor.SafeMemoryMappedViewHandle

-أو-

الخاصية MemoryMappedViewStream.SafeMemoryMappedViewHandle

لتأخير تخصيص الذاكرة حتى يتم إنشاء طريقة عرض (الملفات غير الدائمة فقط).

(لتحديد حجم صفحة النظام الحالية، استخدم الخاصية Environment.SystemPageSize.)

CreateNewأسلوب معMemoryMappedFileOptions.DelayAllocatePagesالقيمة.

-أو-

الأساليب CreateOrOpen التي تحتوي علي قائمة التعداد MemoryMappedFileOptions كمعلمة.

الأمان

يمكنك تطبيق حقوق الوصول عند إنشاء ملفات الذاكرة المعنونة بواسطة استخدام الأساليب التالية التي تأخذ قائمة التعداد MemoryMappedFileAccess كمعلمة:

يمكنك تحديد حقوق الوصول لفتح ملف ذاكرة معنونة موجود مسبقاً باستخدام الأساليب OpenExisting التي تأخذ MemoryMappedFileRights كمعلمة.

بالإضافة إلى ذلك، يمكنك تضمين الكائن MemoryMappedFileSecurity الذي يحتوي على قواعد الوصول المعرّفة مسبقاً.

لتطبيق قواعد وصول جديدة أو معدلة لملف الذاكرةالمعنونة، استخدم الأسلوب SetAccessControl. لاسترداد الوصول أو استخدام قواعد التدقيق من ملف موجود مسبقاً في الأسلوب GetAccessControl.

أمثلة

ملفات الذاكرة المعنونة الدائمة

تنشئ الأساليب CreateFromFile ملف ذاكرة معنونة من ملف موجود على القرص.

ينشئ المثال التالي طريقة عرض خاصة بذاكرة معنونة لجزء من ملف كبير للغاية و يعالج جزء منه.

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Runtime.InteropServices

Class Program

    Sub Main()

        Dim offset As Long = &H10000000 ' 256 megabytes
        Dim length As Long = &H20000000 ' 512 megabytes

        ' Create a memory-mapped view of a portion of an extremely
        ' large image, from the 256th megabyte (the offset) to the
        ' 768th megabyte (the offset plus length).
        Using mmf = _
            MemoryMappedFile.CreateFromFile("c:\ExtremelyLargeImage.data", _
                                                        FileMode.Open,"ImgA")
            Using accessor = mmf.CreateViewAccessor(offset, length)

                Dim colorSize As Integer = Marshal.SizeOf(GetType(MyColor))
                Dim color As MyColor
                Dim i As Long = 0

                ' Make changes to the view.
                Do While (i < length)
                    accessor.Read(i, color)
                    color.Brighten(10)
                    accessor.Write(i, color)
                Loop

            End Using
        End Using
    End Sub
End Class

Public Structure MyColor

    Public Red As Short
    Public Green As Short
    Public Blue As Short
    Public Alpha As Short

    ' Make the view brighter.
    Public Sub Brighten(ByVal value As Short)
        Red = CType(Math.Min(Short.MaxValue, _
            (CType(Red, Integer) + value)), Short)
        Green = CType(Math.Min(Short.MaxValue, _
            (CType(Green, Integer) + value)), Short)
        Blue = CType(Math.Min(Short.MaxValue, _
            (CType(Blue, Integer) + value)), Short)
        Alpha = CType(Math.Min(Short.MaxValue, _
            (CType(Alpha, Integer) + value)), Short)
    End Sub
End Structure
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;

class Program
{
    static void Main(string[] args)
    {
        long offset = 0x10000000; // 256 megabytes
        long length = 0x20000000; // 512 megabytes

        // Create a memory-mapped view of a portion of 
        // an extremely large image, from the 256th megabyte (the offset)
        // to the 768th megabyte (the offset plus length).
        using (var mmf = 
            MemoryMappedFile.CreateFromFile(@"c:\ExtremelyLargeImage.data",
                                                        FileMode.Open,"ImgA"))
        {
            using (var accessor = mmf.CreateViewAccessor(offset, length))
            {

                int colorSize = Marshal.SizeOf(typeof(MyColor));
                MyColor color;

                // Make changes to the view.
                for (long i = 0; i < length; i += colorSize)
                {
                    accessor.Read(i, out color);
                    color.Brighten(10);
                    accessor.Write(i, ref color);
                }
            }
        }

    }

    public struct MyColor
    {
        public short Red;
        public short Green;
        public short Blue;
        public short Alpha;

        // Make the view brigher.
        public void Brighten(short value)
        {
            Red = (short)Math.Min(short.MaxValue, (int)Red + value);
            Green = (short)Math.Min(short.MaxValue, (int)Green + value);
            Blue = (short)Math.Min(short.MaxValue, (int)Blue + value);
            Alpha = (short)Math.Min(short.MaxValue, (int)Alpha + value);
        }
    }

}

يفتح المثال التالي نفس ملف الذاكرة المعنونة من أجل عملية أخرى.

Imports System
Imports System.IO.MemoryMappedFiles
Imports System.Runtime.InteropServices

Class Program
    Public Shared Sub Main(ByVal args As String())
        ' Assumes another process has created the memory-mapped file.
        Using mmf = MemoryMappedFile.OpenExisting("ImgA")
            Using accessor = mmf.CreateViewAccessor(4000000, 2000000)
                Dim colorSize As Integer = Marshal.SizeOf(GetType(MyColor))
                Dim color As MyColor

                ' Make changes to the view.
                Dim i As Long = 0
                While i < 1500000
                    accessor.Read(i, color)
                    color.Brighten(30)
                    accessor.Write(i, color)
                    i += colorSize
                End While
            End Using
        End Using
    End Sub
End Class

Public Structure MyColor
    Public Red As Short
    Public Green As Short
    Public Blue As Short
    Public Alpha As Short

    ' Make the view brigher.
    Public Sub Brighten(ByVal value As Short)
        Red = CShort(Math.Min(Short.MaxValue, CInt(Red) + value))
        Green = CShort(Math.Min(Short.MaxValue, CInt(Green) + value))
        Blue = CShort(Math.Min(Short.MaxValue, CInt(Blue) + value))
        Alpha = CShort(Math.Min(Short.MaxValue, CInt(Alpha) + value))
    End Sub
End Structure
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;


class Program
{
    static void Main(string[] args)
    {
        // Assumes another process has created the memory-mapped file.
        using (var mmf = MemoryMappedFile.OpenExisting("ImgA"))
        {
            using (var accessor = mmf.CreateViewAccessor(4000000, 2000000))
            {
                int colorSize = Marshal.SizeOf(typeof(MyColor));
                MyColor color;

                // Make changes to the view.
                for (long i = 0; i < 1500000; i += colorSize)
                {
                    accessor.Read(i, out color);
                    color.Brighten(20);
                    accessor.Write(i, ref color);
                }
            }
        }
    }
}

public struct MyColor
{
    public short Red;
    public short Green;
    public short Blue;
    public short Alpha;

    // Make the view brigher.
    public void Brighten(short value)
    {
        Red = (short)Math.Min(short.MaxValue, (int)Red + value);
        Green = (short)Math.Min(short.MaxValue, (int)Green + value);
        Blue = (short)Math.Min(short.MaxValue, (int)Blue + value);
        Alpha = (short)Math.Min(short.MaxValue, (int)Alpha + value);
    }
}

ملفات الذاكرة المعنونة غير الدائمة

تنشئ الأساليب CreateNew و CreateOrOpen ملف الذاكرة المعنونة لم يتم تعيينها علي أحد الملفات الموجودة على القرص.

يتكون المثال التاليمن ثلاثة عمليات منفصلة (وحدة تحكم التطبيقات) والتي تقوم بكتابة القيم المنطقية علي ملفات الذاكرة المعنونة. يحدث التسلسل التالي من الإجراءات:

  1. Process Aيقوم بإنشاء ملف معين للذاكرة وكتابة القيمة إلى it.

  2. Process Bيفتح ملف معين للذاكرة وكتابة القيمة إلى it.

  3. Process Cيفتح ملف معين للذاكرة وكتابة القيمة إلى it.

  4. Process Aيقرأ و تعرض قيم من ملفات الذاكرة المعنونة.

  5. بعد Process Aانتهاء استخلاص مع ملف معين للذاكرة، الملف هو مباشرة بواسطة تجميع البيانات المهملة.

لتشغيل هذا المثال ، قم بما يلي:

  1. قم بتحويل التطبيقات برمجياً ثم أفتح ثلاثة نوافذ موجه الأوامر.

  2. في أول نافذة تعجيل الأوامر، قم بتشغيل Process A.

  3. في الأمر الثاني مطالبة الإطار، تشغيل Process B.

  4. الرجوع إلى Process Aو اضغط على Enter الزر.

  5. في نافذة تعجيل الأوامر الثالثة، قم بتشغيل Process C.

  6. الرجوع إلى Process Aو اضغط على Enter الزر.

الإخراج Process Aهو كـ التالي:

Start Process B and press ENTER to continue.
Start Process C and press ENTER to continue.
Process A says: True
Process B says: False
Process C says: True

العملية (أ)

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Threading
Module Module1

    ' Process A:
    Sub Main()
        Using mmf As MemoryMappedFile = MemoryMappedFile.CreateNew("testmap", 10000)
            Dim mutexCreated As Boolean
            Dim mTex As Mutex = New Mutex(True, "testmapmutex", mutexCreated)
            Using Stream As MemoryMappedViewStream = mmf.CreateViewStream()
                Dim writer As BinaryWriter = New BinaryWriter(Stream)
                writer.Write(1)
            End Using
            mTex.ReleaseMutex()
            Console.WriteLine("Start Process B and press ENTER to continue.")
            Console.ReadLine()

            Console.WriteLine("Start Process C and press ENTER to continue.")
            Console.ReadLine()

            mTex.WaitOne()
            Using Stream As MemoryMappedViewStream = mmf.CreateViewStream()
                Dim reader As BinaryReader = New BinaryReader(Stream)
                Console.WriteLine("Process A says: {0}", reader.ReadBoolean())
                Console.WriteLine("Process B says: {0}", reader.ReadBoolean())
                Console.WriteLine("Process C says: {0}", reader.ReadBoolean())
            End Using
            mTex.ReleaseMutex()

        End Using

    End Sub

End Module
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

class Program
{
    // Process A:
    static void Main(string[] args)
    {
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))
        {


            bool mutexCreated;
            Mutex mutex = new Mutex(true, "testmapmutex", out mutexCreated);
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write(1);
            }
            mutex.ReleaseMutex();

            Console.WriteLine("Start Process B and press ENTER to continue.");
            Console.ReadLine();

            Console.WriteLine("Start Process C and press ENTER to continue.");
            Console.ReadLine();

            mutex.WaitOne();
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryReader reader = new BinaryReader(stream);
                Console.WriteLine("Process A says: {0}", reader.ReadBoolean());
                Console.WriteLine("Process B says: {0}", reader.ReadBoolean());
                Console.WriteLine("Process C says: {0}", reader.ReadBoolean());
            }
            mutex.ReleaseMutex();
        }
    }
}

العملية (ب)

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Threading
Module Module1
    ' Process B:
    Sub Main()
        Try
            Using mmf As MemoryMappedFile = MemoryMappedFile.OpenExisting("testmap")
                Dim mTex As Mutex = Mutex.OpenExisting("testmapmutex")
                mTex.WaitOne()
                Using Stream As MemoryMappedViewStream = mmf.CreateViewStream(1, 0)
                    Dim writer As BinaryWriter = New BinaryWriter(Stream)
                    writer.Write(0)
                End Using
                mTex.ReleaseMutex()
            End Using
        Catch noFile As FileNotFoundException
            Console.WriteLine("Memory-mapped file does not exist. Run Process A first." & vbCrLf & noFile.Message)
        End Try

    End Sub

End Module
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

class Program
{
    // Process B:
    static void Main(string[] args)
    {
        try
        {
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
            {

                Mutex mutex = Mutex.OpenExisting("testmapmutex");
                mutex.WaitOne();

                using (MemoryMappedViewStream stream = mmf.CreateViewStream(1, 0))
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(0);
                }
                mutex.ReleaseMutex();
            }
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
        }
    }
}

العملية (ج)

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Threading
Module Module1
    ' Process C:
    Sub Main()
        Try
            Using mmf As MemoryMappedFile = MemoryMappedFile.OpenExisting("testmap")
                Dim mTex As Mutex = Mutex.OpenExisting("testmapmutex")
                mTex.WaitOne()
                Using Stream As MemoryMappedViewStream = mmf.CreateViewStream(2, 0)
                    Dim writer As BinaryWriter = New BinaryWriter(Stream)
                    writer.Write(1)
                End Using
                mTex.ReleaseMutex()
            End Using
        Catch noFile As FileNotFoundException
            Console.WriteLine("Memory-mapped file does not exist. Run Process A first, then B." & vbCrLf & noFile.Message)
        End Try

    End Sub

End Module
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

class Program
{
    // Process C:
    static void Main(string[] args)
    {
        try
        {
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
            {

                Mutex mutex = Mutex.OpenExisting("testmapmutex");
                mutex.WaitOne();

                using (MemoryMappedViewStream stream = mmf.CreateViewStream(2, 0))
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(1);
                }
                mutex.ReleaseMutex();
            }
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("Memory-mapped file does not exist. Run Process A first, then B.");
        }
    }
}

راجع أيضًا:

موارد أخرى

ملف و تدفق ال I/O