Предоставляет ли .net-инфраструктуру методы async для работы с файловой системой?

Существует ли в .NET-инфраструктуре встроенная библиотека/сборка async, которая позволяет работать с файловой системой (например, File.ReadAllBytes, File.WriteAllBytes)?

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

Что-то вроде этого было бы неплохо:

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

Ответ 1

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

Да. Существуют асинхронные методы работы с файловой системой, но не для вспомогательных методов статического типа 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);
}

Ответ 2

Он уже делает это. См. Например Использование Async для доступа к файлам. Статья 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);
    };
}

Ответ 3

Существует ли в .NET-инфраструктуре встроенная библиотека/сборка async, которая позволяет работать с файловой системой (например, File.ReadAllBytes, File.WriteAllBytes)?

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

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

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

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

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

Ответ 4

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

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 end