.net 框架是否具有允许使用文件系统(例如, )的async
内置库/程序集?File.ReadAllBytes
File.WriteAllBytes
还是我必须使用 and 的方法编写自己的async
库?StreamReader
StreamWriter
像这样的东西会很不错:
var bytes = await File.ReadAllBytes("my-file.whatever");
.net 框架是否具有允许使用文件系统(例如, )的async
内置库/程序集?File.ReadAllBytes
File.WriteAllBytes
还是我必须使用 and 的方法编写自己的async
库?StreamReader
StreamWriter
像这样的东西会很不错:
var bytes = await File.ReadAllBytes("my-file.whatever");
.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);
}
它已经做到了。例如,请参阅使用异步进行文件访问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);
};
}
.net 框架是否具有允许使用文件系统的异步内置库/程序集(例如 File.ReadAllBytes、File.WriteAllBytes)?
不幸的是,当涉及到异步文件操作时,桌面 API 有点参差不齐。正如您所指出的,许多不错的便捷方法没有异步等效方法。还缺少文件的异步打开(这在通过网络共享打开文件时特别有用)。
我希望随着世界转向 .NET Core,这些 API 将被添加。
还是我必须使用 StreamReader 和 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
来创建相同的行为。
以下是我为 a 创建的辅助方法NetStandart 2.0 class library
,它们在NetCore 3.1
和NetFramework 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();
}