2016-03-02 5 views
13

Hat das .net-Framework eine integrierte Bibliothek/Assembly async, die es ermöglicht, mit dem Dateisystem zu arbeiten (z. B. File.ReadAllBytes, File.WriteAllBytes)?Bietet das .NET-Framework asynchrone Methoden zum Arbeiten mit dem Dateisystem?

Oder muss ich meine eigene Bibliothek mit den async Methoden von StreamReader und StreamWriter schreiben?

So etwas wäre ziemlich schön sein:

var bytes = await File.ReadAllBytes("my-file.whatever"); 

Antwort

13

Hat das .net Framework ein asynchrones hat integrierte Bibliothek/Baugruppe, die mit dem Dateisystem

Ja arbeiten können. Es gibt asynchrone Methoden für die Arbeit mit dem Dateisystem, aber nicht für die Hilfsmethoden auf dem statischen File-Typ. Sie sind auf FileStream.

So gibt es keine File.ReadAllBytesAsync aber es gibt FileStream.ReadAsync usw. Zum Beispiel:

byte[] result; 
using (FileStream stream = File.Open(@"C:\file.txt", FileMode.Open)) 
{ 
    result = new byte[stream.Length]; 
    await stream.ReadAsync(result, 0, (int)stream.Length); 
} 
+0

Wenn die Datei, die Sie in einen Bytestream serialisiert haben, groß war (3gb +), besteht die Möglichkeit, dass die Streamlänge größer ist als ein Int-Typ, der sie speichern und überlaufen lässt? – Dave

+1

@Dave wahrscheinlich. In solchen Fällen müssen Sie wahrscheinlich Chunks einlesen. – i3arnon

+0

Sie sollten Logik haben, in Blöcke unabhängig zu lesen. Laut [Microsoft-Dokumentation] (https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream.readasync?view=netframework-4.7.1#System_IO_FileStream_ReadAsync_System_Byte___System_Int32_System_Int32_System_Threading_CancellationToken_) kann ReadAsync nicht garantiert gefüllt werden das ganze Array. Sie müssen den Rückgabewert überprüfen, um zu sehen, wie viel _ _actually_ gelesen wird. – Phil

11

Es es bereits der Fall ist. Siehe beispielsweise Using Async for File Access MSDN-Artikel.

private async Task WriteTextAsync(string filePath, string text) 
{ 
    byte[] encodedText = Encoding.Unicode.GetBytes(text); 

    using (FileStream sourceStream = new FileStream(filePath, 
     FileMode.Append, FileAccess.Write, FileShare.None, 
     bufferSize: 4096, useAsync: true)) 
    { 
     await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); 
    }; 
} 
-7

Wenn Sie eine Datei in einer Hintergrundaufgabe zu schreiben haben Sie sie schreiben sincronously in einer Asynchron-Methode.

static void Main(string[] args) 
{ 
    Console.WriteLine("1"); 
    // thread 1, sync 
    byte[] dataToWrite = System.Text.ASCIIEncoding.ASCII.GetBytes("my custom data"); 
    Task.Run(() => 
    { 
     Console.WriteLine("2"); 
     // aspetto un secondo 
     System.Threading.Thread.Sleep(1000); 
     // thread 2, async code 
     System.IO.File.WriteAllBytes(@"c:\temp\prova.txt", dataToWrite); 
     Console.WriteLine("2, end"); 
    }); 

    Console.WriteLine("3, exit"); 

    Console.ReadLine(); 
    // thread 1 
} 

wird die Ausführung ausgegeben werden: 1,3,2,2 Ende

+5

Dies ist nicht asynchron und ein sehr schlechter Rat. – i3arnon

+0

Sie erwarten diese Aufgabe nicht. Auch das nutzt kaum IOCP – MickyD

+0

, warum es nicht async ist, tut mir leid? Es kann verwendet werden, wenn Sie im Hintergrund schreiben müssen ohne Ende des Schreibvorgangs –

4

Hat die FRAMEWORK einen async integrierte Bibliothek/Baugruppe, die mit dem Dateisystem zu arbeiten, ermöglicht hat (zB File.ReadAllBytes, File.WriteAllBytes)?

Leider sind die Desktop-APIs bei asynchronen Dateioperationen ein wenig fleckig. Wie Sie festgestellt haben, gibt es bei einigen netten Convenience-Methoden keine asynchronen Entsprechungen. Außerdem fehlen asynchrone Öffnen von von Dateien (was besonders nützlich beim Öffnen von Dateien über eine Netzwerkfreigabe ist).

Ich hoffe, dass diese APIs hinzugefügt werden, wie die Welt zu .NET Core bewegt.

Oder muss ich meine eigene Bibliothek mit den asynchronen Methoden von StreamReader und StreamWriter schreiben?

Das ist der beste Ansatz jetzt.

Beachten Sie, dass, wenn ReadAsync/WriteAsync und Freunde verwenden, müssen Sie die Datei explizit für asynchronen Zugriff öffnen. Die einzige Möglichkeit, dies (derzeit) zu tun, besteht darin, eine Konstruktorüberladung zu verwenden, die einen bool isAsync Parameter (übergibt true) oder einen FileOptions Parameter (übergibt FileOptions.Asynchronous). Sie können also keine offenen Methoden wie File.Open verwenden.

+1

Danke für diese Informationen und vor allem: 'FileOptions.Asynchronous' Danke! 'isAsync' scheint entzogen zu sein. +1 – BendEg