Exportieren (0) Drucken
Alle erweitern
Dieser Artikel wurde manuell übersetzt. Bewegen Sie den Mauszeiger über die Sätze im Artikel, um den Originaltext anzuzeigen. Weitere Informationen
Übersetzung
Original

Gewusst wie: Verwenden der ReadFile-Funktion von Windows (C#-Programmierhandbuch)

In diesem Beispiel wird durch das Lesen und Anzeigen einer Textdatei die ReadFile-Funktion von Windows veranschaulicht. Für die ReadFile-Funktion muss unsafe-Code verwendet werden, da ein Zeiger als Parameter benötigt wird.

Das an die Read-Funktion übergebene Bytearray ist ein verwalteter Typ. Dies bedeutet, dass der Garbage Collector der Common Language Runtime (CLR) den vom Array belegten Speicher beliebig verschieben kann. Um dies zu verhindern, wird mithilfe von fixed ein Zeiger auf den Speicher abgerufen und gekennzeichnet, damit der Garbage Collector diesen nicht verschieben kann. Am Ende des fixed-Blocks wird der Speicher automatisch wieder in den Zustand zurückgesetzt, in dem er Verschiebungen durch die Garbage Collection unterliegt.

Diese Möglichkeit wird als deklaratives Fixieren bezeichnet. Beim Fixieren ist der Verwaltungsaufwand sehr gering, sofern die Garbage Collection nicht im fixed-Block auftritt. Dies ist jedoch nur sehr selten der Fall. Fixieren kann jedoch zu einigen unerwünschten Seiteneffekten beim Ausführen der globalen Garbage Collection führen. Die Garbage Collector-Fähigkeit zum Komprimieren von Speicher wird durch fixierte Puffer stark beeinträchtigt. Aus diesem Grund sollte das Fixieren nach Möglichkeit vermieden werden.

class FileReader
{
    const uint GENERIC_READ = 0x80000000;
    const uint OPEN_EXISTING = 3;
    System.IntPtr handle;

    [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
    static extern unsafe System.IntPtr CreateFile
    (
        string FileName,          // file name 
        uint DesiredAccess,       // access mode 
        uint ShareMode,           // share mode 
        uint SecurityAttributes,  // Security Attributes 
        uint CreationDisposition, // how to create 
        uint FlagsAndAttributes,  // file attributes 
        int hTemplateFile         // handle to template file
    );

    [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool ReadFile
    (
        System.IntPtr hFile,      // handle to file 
        void* pBuffer,            // data buffer 
        int NumberOfBytesToRead,  // number of bytes to read 
        int* pNumberOfBytesRead,  // number of bytes read 
        int Overlapped            // overlapped buffer
    );

    [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool CloseHandle
    (
        System.IntPtr hObject // handle to object
    );

    public bool Open(string FileName)
    {
        // open the existing file for reading       
        handle = CreateFile
        (
            FileName,
            GENERIC_READ,
            0,
            0,
            OPEN_EXISTING,
            0,
            0
        );

        if (handle != System.IntPtr.Zero)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public unsafe int Read(byte[] buffer, int index, int count)
    {
        int n = 0;
        fixed (byte* p = buffer)
        {
            if (!ReadFile(handle, p + index, count, &n, 0))
            {
                return 0;
            }
        }
        return n;
    }

    public bool Close()
    {
        return CloseHandle(handle);
    }
}

class Test
{
    static int Main(string[] args)
    {
        if (args.Length != 1)
        {
            System.Console.WriteLine("Usage : ReadFile <FileName>");
            return 1;
        }

        if (!System.IO.File.Exists(args[0]))
        {
            System.Console.WriteLine("File " + args[0] + " not found.");
            return 1;
        }

        byte[] buffer = new byte[128];
        FileReader fr = new FileReader();

        if (fr.Open(args[0]))
        {
            // Assume that an ASCII file is being read.
            System.Text.ASCIIEncoding Encoding = new System.Text.ASCIIEncoding();

            int bytesRead;
            do
            {
                bytesRead = fr.Read(buffer, 0, buffer.Length);
                string content = Encoding.GetString(buffer, 0, bytesRead);
                System.Console.Write("{0}", content);
            }
            while (bytesRead > 0);

            fr.Close();
            return 0;
        }
        else
        {
            System.Console.WriteLine("Failed to open requested file");
            return 1;
        }
    }
}

Community-Beiträge

Anzeigen:
© 2015 Microsoft