2016-03-02 5 views
13

Имеет ли инфраструктура .net встроенная библиотека/сборка async, которая позволяет работать с файловой системой (например, File.ReadAllBytes, File.WriteAllBytes)?Предоставляет ли .net-инфраструктуру методы async для работы с файловой системой?

Или мне нужно написать свою собственную библиотеку, используя async Методы StreamReader и StreamWriter?

Нечто подобное было бы очень приятно:

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

ответ

13

ли рамки .net имеют асинхра встроенной библиотеки/сборку, которая позволяет работать с файловой системой

Да. Существуют асинхронные методы работы с файловой системой, но не для вспомогательных методов статического типа File. Они находятся на FileStream.

Таким образом, нет File.ReadAllBytesAsync но есть FileStream.ReadAsync и т.д. Например:

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

Если файл, который вы сериализовали в поток байтов, был большим (3gb +), существует ли вероятность того, что длина потока будет иметь значение больше, чем тип int может хранить и блокировать его переполнением? – Dave

+1

@ Возможно, вероятно. В таких случаях вам, вероятно, нужно читать куски. – i3arnon

+0

У вас должна быть логика, чтобы читать в кусках независимо. Согласно [документации Microsoft] (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_), ReadAsync не может быть заполнен весь массив. Вам нужно проверить возвращаемое значение, чтобы увидеть, сколько он _actually_ читает. – Phil

11

Это уже делает это. См. Например, статью Using Async for File Access MSDN.

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

Если вы должны написать файл в фоновом режиме, вы можете написать его sincronously в методе асинхронным.

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 
} 

выход выполнения будет: 1,3,2,2 конца

+5

Это не асинхронный и очень плохой совет. – i3arnon

+0

Вы не ожидаете выполнения этой задачи. Кроме того, это вряд ли использует IOCP – MickyD

+0

, почему это не async извините? Его можно использовать, если вам нужно писать в фоновом режиме без конца ожидания записи –

4

ли рамки .net имеют асинхра встроенной библиотеки/сборку, которая позволяет работать с файловой системой (например File.ReadAllBytes, File.WriteAllBytes)?

К сожалению, API-интерфейсы рабочего стола являются немного пятнистыми, когда речь заходит о асинхронных файловых операциях. Как вы отметили, ряд полезных методов удобства не имеет асинхронных эквивалентов. Также отсутствуют асинхронные открытие файлов (что особенно полезно при открытии файлов по сетевому ресурсу).

Я надеюсь, что эти API будут добавлены, когда мир перейдет на .NET Core.

Или мне нужно написать свою собственную библиотеку, используя методы async для StreamReader и StreamWriter?

Это лучший подход прямо сейчас.

Обратите внимание, что при использовании ReadAsync/WriteAsync и друзей, вы должны явно открыть файл для асинхронного доступа. Единственный способ сделать это (в настоящее время) - использовать перегрузку конструктора FileStream, которая принимает параметр bool isAsync (минус true) или параметр FileOptions (минус FileOptions.Asynchronous). Таким образом, вы не можете использовать методы открытого доступа, такие как File.Open.

+1

Спасибо за эту информацию, и особенно: 'FileOptions.Asynchronous' спасибо! 'isAsync', кажется, лишен. +1 – BendEg