39

.net 框架是否具有允许使用文件系统(例如, )的async内置库/程序集?File.ReadAllBytesFile.WriteAllBytes

还是我必须使用 and 的方法编写自己的async库?StreamReaderStreamWriter

像这样的东西会很不错:

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

5 回答 5

47

.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);
}
于 2016-03-02T14:54:18.867 回答
19

它已经做到了。例如,请参阅使用异步进行文件访问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);
    };
}
于 2016-03-02T14:53:52.737 回答
11

.net 框架是否具有允许使用文件系统的异步内置库/程序集(例如 File.ReadAllBytes、File.WriteAllBytes)?

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

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

还是我必须使用 StreamReader 和 StreamWriter 的异步方法编写自己的库?

这是目前最好的方法。

注意,使用ReadAsync/WriteAsync和好友时,必须显式打开文件进行异步访问。(当前)执行此操作的唯一方法是使用带有参数(传递)或参数(传递)的FileStream构造函数重载。所以你不能使用方便的打开方法,比如.bool isAsynctrueFileOptionsFileOptions.AsynchronousFile.Open

于 2016-03-03T13:34:38.147 回答
6

在 .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 中仍然缺少它们。

于 2018-10-17T14:52:14.697 回答
0

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

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

这些实现与net core 3.1 / net standard 2.1类方法的名称和签名完全匹配File,因此您只需将它们放在任何公共类中即可。(例如 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();
    }
于 2021-09-13T11:08:58.153 回答