.net 框架是否提供使用文件系统的异步方法?
Does the .net framework provides async methods for working with the file-system?
.net 框架是否有 async
内置 library/assembly 允许使用文件系统(例如 File.ReadAllBytes
、File.WriteAllBytes
)?
或者我是否必须使用 StreamReader
和 StreamWriter
的 async
方法编写自己的库?
像这样的东西会很不错:
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.1
和 NetFramework 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();
}
.net 框架是否有 async
内置 library/assembly 允许使用文件系统(例如 File.ReadAllBytes
、File.WriteAllBytes
)?
或者我是否必须使用 StreamReader
和 StreamWriter
的 async
方法编写自己的库?
像这样的东西会很不错:
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.1
和 NetFramework 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();
}