.net 框架是否提供使用文件系统的异步方法?

Does the .net framework provides async methods for working with the file-system?

.net 框架是否有 async 内置 library/assembly 允许使用文件系统(例如 File.ReadAllBytesFile.WriteAllBytes)?

或者我是否必须使用 StreamReaderStreamWriterasync 方法编写自己的库?

像这样的东西会很不错:

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

它已经做到了。例如,参见 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);
    };
}

Does the .net framework has an async built-in library/assembly which allows to work with the file system

是的。有用于处理文件系统的异步方法,但没有用于静态 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);
}

Does the .net framework has an async built-in library/assembly which allows to work with the file system (e.g. File.ReadAllBytes, File.WriteAllBytes)?

不幸的是,在异步文件操作方面,桌面 API 有点参差不齐。正如您所指出的,许多不错的便捷方法没有异步等效方法。还缺少异步 打开 文件(这在通过网络共享打开文件时特别有用)。

我希望随着世界转向 .NET Core,这些 API 将被添加。

Or do I have to write my own library using the async Methods of StreamReader and StreamWriter?

这是目前最好的方法。

注意使用ReadAsync/WriteAsync等朋友时,必须显式打开文件进行异步访问。这样做(目前)的唯一方法是使用一个 FileStream 构造函数重载,它接受一个 bool isAsync 参数(传递 true)或一个 FileOptions 参数(传递 FileOptions.Asynchronous).所以你不能使用像File.Open.

这样方便的打开方法

在 .NET 核心中(从 2.0 版开始)现在有相应 ReadAll/WriteAll/AppendAll 方法的所有异步风格,例如:

File.(Read|Write|Append)All(Text|Lines|Bytes)Async

https://docs.microsoft.com/en-us/dotnet/api/system.io.file.readallbytesasync?view=netcore-2.1

遗憾的是,.NET 标准 2.0 中仍然缺少它们。

不,但您可以使用 FileStream 创建相同的行为。

这是我为 NetStandart 2.0 class library 创建的辅助方法,它们在 NetCore 3.1NetFramework 4.7.2 项目中都使用过。

这些实现已经完全匹配了net core 3.1 / net standard 2.1 File class方法的名称和签名,所以你只需要将它们放在任何public class。 (例如 FileHelper...):

另外,这应该是最高效的,类似于.net实现的源代码。

private const int DefaultBufferSize = 4096;

    // File accessed asynchronous reading and sequentially from beginning to end.
    private const FileOptions DefaultOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;

    public static async Task WriteAllTextAsync(string filePath, string text)
    {
        byte[] encodedText = Encoding.Unicode.GetBytes(text);

        using FileStream sourceStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None,
            DefaultBufferSize, true);
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    }

    public static async Task<IEnumerable<string>> ReadAllLinesAsync(string filePath)
    {
        var lines = new List<string>();

        using var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read,
            DefaultBufferSize, DefaultOptions);
        using var reader = new StreamReader(sourceStream, Encoding.Unicode);
        string line;
        while ((line = await reader.ReadLineAsync()) != null) lines.Add(line);

        return lines;
    }

    public static async Task<string> ReadAllTextAsync(string filePath)
    {
        using var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read,
            DefaultBufferSize, DefaultOptions);
        using var reader = new StreamReader(sourceStream, Encoding.Unicode);
        return await reader.ReadToEndAsync();
    }