SpeicherabbilddateienMemory-Mapped Files

Eine Speicherabbilddatei enthält den Inhalt einer Datei im virtuellen Speicher.A memory-mapped file contains the contents of a file in virtual memory. Diese Zuordnung zwischen einer Datei und Speicherplatz ermöglicht es einer Anwendung mit mehreren Prozessen, die Datei durch direktes Lesen und Schreiben im Arbeitsspeicher zu ändern.This mapping between a file and memory space enables an application, including multiple processes, to modify the file by reading and writing directly to the memory. Ab .NET Framework 4 können Sie verwalteten Code verwenden, um auf die gleiche Weise auf Speicherabbilddateien zuzugreifen wie native Windows-Funktionen. Dies wird unter Managing Memory-Mapped Files (Verwalten von im Speicher abgebildeten Dateien) beschrieben.Starting with the .NET Framework 4, you can use managed code to access memory-mapped files in the same way that native Windows functions access memory-mapped files, as described in Managing Memory-Mapped Files.

Es gibt zwei Arten von Speicherabbilddateien:There are two types of memory-mapped files:

  • Beibehaltene SpeicherabbilddateienPersisted memory-mapped files

    Persistent gespeicherte Dateien sind Speicherabbilddateien, die einer Quelldatei auf einem Datenträger zugeordnet sind.Persisted files are memory-mapped files that are associated with a source file on a disk. Wenn der letzte Prozess die Verwendung der Datei beendet, werden die Daten in der Quelldatei auf dem Datenträger gespeichert.When the last process has finished working with the file, the data is saved to the source file on the disk. Diese Speicherabbilddateien eignen sich für extrem große Quelldateien.These memory-mapped files are suitable for working with extremely large source files.

  • Nicht beibehaltene SpeicherabbilddateienNon-persisted memory-mapped files

    Nicht persistent gespeicherte Dateien sind Speicherabbilddateien, die keiner Datei auf einem Datenträger zugeordnet sind.Non-persisted files are memory-mapped files that are not associated with a file on a disk. Wenn der letzte Prozess die Verwendung der Datei beendet, gehen die Daten verloren, und die Datei wird von der Garbage Collection freigegeben.When the last process has finished working with the file, the data is lost and the file is reclaimed by garbage collection. Diese Dateien eignen sich zum Erstellen von freigegebenen Speicherbereichen für die prozessübergreifende Kommunikation (IPC).These files are suitable for creating shared memory for inter-process communications (IPC).

Prozesse, Ansichten und Verwalten des ArbeitsspeichersProcesses, Views, and Managing Memory

Speicherabbilddateien können für mehrere Prozesse verwendet werden.Memory-mapped files can be shared across multiple processes. Prozesse können mithilfe eines allgemeinen Namens der gleichen Speicherabbilddatei zugeordnet werden. Dieser allgemeine Name wird von dem Prozess zugewiesen, durch den die Datei erstellt wird.Processes can map to the same memory-mapped file by using a common name that is assigned by the process that created the file.

Zur Verwendung einer Speicherabbilddatei müssen Sie eine Ansicht der gesamten Speicherabbilddatei oder eines Teils davon erstellen.To work with a memory-mapped file, you must create a view of the entire memory-mapped file or a part of it. Sie können auch mehrere Ansichten für identische Teile der Speicherabbilddatei und dadurch parallelen Arbeitsspeicher erstellen.You can also create multiple views to the same part of the memory-mapped file, thereby creating concurrent memory. Parallele Ansichten müssen aus der gleichen Speicherabbilddatei erstellt werden.For two views to remain concurrent, they have to be created from the same memory-mapped file.

Mehrere Ansichten können auch erforderlich sein, wenn die Datei größer als der für die Speicherzuordnung verfügbare logische Speicher der Anwendung ist (2 GB auf einem 32-Bit-Computer).Multiple views may also be necessary if the file is greater than the size of the application’s logical memory space available for memory mapping (2 GB on a 32-bit computer).

Zwei Arten von Ansichten werden verwendet: die Streamzugriffsansicht und die Ansicht für direkten Zugriff.There are two types of views: stream access view and random access view. Verwenden Sie für den sequenziellen Zugriff auf eine Datei Streamzugriffsansichten. Dies wird für nicht dauerhaft gespeicherte Dateien und IPC empfohlen.Use stream access views for sequential access to a file; this is recommended for non-persisted files and IPC. Die Ansichten für direkten Zugriff werden beim Arbeiten mit persistent gespeicherten Dateien vorgezogen.Random access views are preferred for working with persisted files.

Der Zugriff auf Speicherabbilddateien erfolgt über den Speicher-Manager des Betriebssystems. Die Datei wird daher automatisch in eine Reihe von Seiten partitioniert und nach Bedarf verwendet.Memory-mapped files are accessed through the operating system’s memory manager, so the file is automatically partitioned into a number of pages and accessed as needed. Die Speicherverwaltung wird automatisch ausgeführt.You do not have to handle the memory management yourself.

Die folgende Abbildung zeigt, wie für mehrere Prozesse gleichzeitig mehrere überlappende Ansichten derselben Speicherabbilddatei vorhanden sein können.The following illustration shows how multiple processes can have multiple and overlapping views to the same memory-mapped file at the same time.

Die folgende Abbildung zeigt mehrere überlappende Ansichten für eine Speicherabbilddatei:The following image shows multiple and overlapped views to a memory-mapped file:

Screenshot mit Ansichten für eine Speicherabbilddatei

Programmieren mit SpeicherabbilddateienProgramming with Memory-Mapped Files

Die folgende Tabelle enthält Informationen zur Verwendung von Speicherabbilddatei-Objekten und ihren Membern.The following table provides a guide for using memory-mapped file objects and their members.

AufgabeTask Zu verwendende Methoden oder EigenschaftenMethods or properties to use
Abrufen eines MemoryMappedFile-Objekts, das eine persistent gespeicherte Speicherabbilddatei darstellt, aus einer Datei auf DatenträgerTo obtain a MemoryMappedFile object that represents a persisted memory-mapped file from a file on disk. MemoryMappedFile.CreateFromFile -Methode.MemoryMappedFile.CreateFromFile method.
Abrufen eines MemoryMappedFile-Objekts, das eine nicht persistent gespeicherte Speicherabbilddatei darstellt (keiner Datei auf Datenträger zugeordnet)To obtain a MemoryMappedFile object that represents a non-persisted memory-mapped file (not associated with a file on disk). MemoryMappedFile.CreateNew -Methode.MemoryMappedFile.CreateNew method.

- oder -- or -

MemoryMappedFile.CreateOrOpen -Methode.MemoryMappedFile.CreateOrOpen method.
Abrufen eines MemoryMappedFile-Objekts einer vorhandenen Speicherabbilddatei (persistent gespeichert oder nicht persistent gespeichert)To obtain a MemoryMappedFile object of an existing memory-mapped file (either persisted or non-persisted). MemoryMappedFile.OpenExisting -Methode.MemoryMappedFile.OpenExisting method.
Abrufen eines UnmanagedMemoryStream-Objekts für eine Ansicht für den sequenziellen Zugriff auf die SpeicherabbilddateiTo obtain a UnmanagedMemoryStream object for a sequentially accessed view to the memory-mapped file. MemoryMappedFile.CreateViewStream -Methode.MemoryMappedFile.CreateViewStream method.
Abrufen eines UnmanagedMemoryAccessor-Objekts für eine Ansicht für den direkten Zugriff auf die SpeicherabbilddateiTo obtain a UnmanagedMemoryAccessor object for a random access view to a memory-mapped fie. MemoryMappedFile.CreateViewAccessor -Methode.MemoryMappedFile.CreateViewAccessor method.
Abrufen eines SafeMemoryMappedViewHandle-Objekts, das mit nicht verwaltetem Code verwendet wirdTo obtain a SafeMemoryMappedViewHandle object to use with unmanaged code. MemoryMappedFile.SafeMemoryMappedFileHandle-Eigenschaft.MemoryMappedFile.SafeMemoryMappedFileHandle property.

- oder -- or -

MemoryMappedViewAccessor.SafeMemoryMappedViewHandle-Eigenschaft.MemoryMappedViewAccessor.SafeMemoryMappedViewHandle property.

- oder -- or -

MemoryMappedViewStream.SafeMemoryMappedViewHandle-Eigenschaft.MemoryMappedViewStream.SafeMemoryMappedViewHandle property.
Verzögern der Speicherbelegung, bis eine Ansicht erstellt wird (nur nicht persistent gespeicherte Dateien)To delay allocating memory until a view is created (non-persisted files only).

(Verwenden Sie die Environment.SystemPageSize-Eigenschaft, um die aktuelle Systemseitengröße zu bestimmen.)(To determine the current system page size, use the Environment.SystemPageSize property.)
Die CreateNew-Methode mit dem MemoryMappedFileOptions.DelayAllocatePages-Wert.CreateNew method with the MemoryMappedFileOptions.DelayAllocatePages value.

- oder -- or -

CreateOrOpen-Methoden mit einer MemoryMappedFileOptions-Enumeration als ParameterCreateOrOpen methods that have a MemoryMappedFileOptions enumeration as a parameter.

SicherheitSecurity

Mit den folgenden Methoden, die eine MemoryMappedFileAccess-Enumeration als Parameter akzeptieren, können beim Erstellen einer Speicherabbilddatei Zugriffsrechte angewendet werden:You can apply access rights when you create a memory-mapped file, by using the following methods that take a MemoryMappedFileAccess enumeration as a parameter:

Sie können mit den OpenExisting-Methoden, die MemoryMappedFileRights als Parameter akzeptieren, Zugriffsrechte für das Öffnen einer vorhandenen Speicherabbilddatei angeben.You can specify access rights for opening an existing memory-mapped file by using the OpenExisting methods that take an MemoryMappedFileRights as a parameter.

Außerdem können Sie ein MemoryMappedFileSecurity-Objekt einschließen, das vordefinierte Zugriffsregeln enthält.In addition, you can include a MemoryMappedFileSecurity object that contains predefined access rules.

Verwenden Sie die SetAccessControl-Methode, um neue oder geänderte Zugriffsregeln auf eine Speicherabbilddatei anzuwenden.To apply new or changed access rules to a memory-mapped file, use the SetAccessControl method. Mit der GetAccessControl-Methode können Zugriffs- oder Überwachungsregeln aus einer vorhandenen Datei abgerufen werden.To retrieve access or audit rules from an existing file, use the GetAccessControl method.

BeispieleExamples

Beibehaltene SpeicherabbilddateienPersisted Memory-Mapped Files

Die CreateFromFile-Methoden erstellen eine Speicherabbilddatei aus einer vorhandenen Datei auf einem Datenträger.The CreateFromFile methods create a memory-mapped file from an existing file on disk.

Im folgenden Beispiel wird ein Speicherabbild für einen Teil einer sehr großen Datei erstellt und teilweise bearbeitet.The following example creates a memory-mapped view of a part of an extremely large file and manipulates a portion of it.

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 the memory-mapped file.
        using (var mmf = MemoryMappedFile.CreateFromFile(@"c:\ExtremelyLargeImage.data", FileMode.Open,"ImgA"))
        {
            // Create a random access view, from the 256th megabyte (the offset)
            // to the 768th megabyte (the offset plus length).
            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 brighter.
    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.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 the memory-mapped file.
        Using mmf = MemoryMappedFile.CreateFromFile("c:\ExtremelyLargeImage.data", FileMode.Open, "ImgA")
            ' Create a random access view, from the 256th megabyte (the offset)
            ' to the 768th megabyte (the offset plus length).
            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)
                    i += colorSize
                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

Im folgenden Beispiel wird die gleiche Speicherabbilddatei für einen anderen Prozess geöffnet.The following example opens the same memory-mapped file for another process.

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);
    }
}
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

Nicht beibehaltene SpeicherabbilddateienNon-Persisted Memory-Mapped Files

Die CreateNew-Methode und die CreateOrOpen-Methode erstellen eine Speicherabbilddatei, die keiner vorhandenen Datei auf einem Datenträger zugeordnet ist.The CreateNew and CreateOrOpen methods create a memory-mapped file that is not mapped to an existing file on disk.

Das folgende Beispiel umfasst drei separate Prozesse (Konsolenanwendungen), die boolesche Werte in eine Speicherabbilddatei schreiben.The following example consists of three separate processes (console applications) that write Boolean values to a memory-mapped file. Die folgende Sequenz von Aktionen wird ausgeführt:The following sequence of actions occur:

  1. Process A erstellt die Speicherabbilddatei und schreibt in diese einen Wert.Process A creates the memory-mapped file and writes a value to it.

  2. Process B erstellt die Speicherabbilddatei und schreibt in diese einen Wert.Process B opens the memory-mapped file and writes a value to it.

  3. Process C erstellt die Speicherabbilddatei und schreibt in diese einen Wert.Process C opens the memory-mapped file and writes a value to it.

  4. Process A liest die Werte in der Speicherabbilddatei und zeigt diese an.Process A reads and displays the values from the memory-mapped file.

  5. Nachdem die Bearbeitung der Speicherabbilddatei durch Process A abgeschlossen ist, wird die Datei sofort von der Garbage Collection freigegeben.After Process A is finished with the memory-mapped file, the file is immediately reclaimed by garbage collection.

Gehen Sie folgendermaßen vor, um dieses Beispiel auszuführen:To run this example, do the following:

  1. Kompilieren Sie die Anwendungen, und öffnen Sie drei Eingabeaufforderungsfenster.Compile the applications and open three Command Prompt windows.

  2. Führen Sie Process A im ersten Eingabeaufforderungsfenster aus.In the first Command Prompt window, run Process A.

  3. Führen Sie Process B im zweiten Eingabeaufforderungsfenster aus.In the second Command Prompt window, run Process B.

  4. Kehren Sie zu Process A zurück, und drücken Sie die EINGABETASTE.Return to Process A and press ENTER.

  5. Führen Sie Process C im dritten Eingabeaufforderungsfenster aus.In the third Command Prompt window, run Process C.

  6. Kehren Sie zu Process A zurück, und drücken Sie die EINGABETASTE.Return to Process A and press ENTER.

Die Ausgabe von Process A lautet wie folgt:The output of Process A is as follows:

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  

Prozess AProcess A

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 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

Prozess BProcess B

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 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

Prozess CProcess C

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.");
        }
    }
}
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

Siehe auchSee also