我有一个从文件创建MessageDigest(哈希)的方法,我需要对很多文件(> = 100,000)执行此操作.我应该用多大的缓冲区来读取文件以最大限度地提高性能?
大多数人都熟悉基本代码(我将在这里重复以防万一):
MessageDigest md = MessageDigest.getInstance( "SHA" );
FileInputStream ios = new FileInputStream( "myfile.bmp" );
byte[] buffer = new byte[4 * 1024]; // what should this value be?
int read = 0;
while( ( read = ios.read( buffer ) ) > 0 )
md.update( buffer, 0, read );
ios.close();
md.digest();
Run Code Online (Sandbox Code Playgroud)
什么是最大化吞吐量的缓冲区的理想大小?我知道这是依赖于系统的,我很确定它的操作系统,文件系统和硬盘依赖,并且可能还有其他硬件/软件.
(我应该指出,我对Java有点新手,所以这可能只是一些我不知道的Java API调用.)
编辑:我不提前知道将要使用的系统类型,所以我不能假设很多.(因为那个原因,我正在使用Java.)
编辑:上面的代码缺少像try..catch这样的东西,以使帖子更小
我的问题在于文件复制性能.我们有一个媒体管理系统,需要在文件系统上大量移动文件到不同的位置,包括同一网络上的Windows共享,FTP站点,AmazonS3等.当我们都在一个Windows网络上时,我们可以使用System.IO.File.Copy(源,目标)复制文件.由于我们所拥有的很多次都是输入流(如MemoryStream),我们尝试抽象复制操作以获取输入流和输出流,但我们看到了大量的性能下降.下面是一些用于复制文件以用作讨论点的代码.
public void Copy(System.IO.Stream inStream, string outputFilePath)
{
int bufferSize = 1024 * 64;
using (FileStream fileStream = new FileStream(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write))
{
int bytesRead = -1;
byte[] bytes = new byte[bufferSize];
while ((bytesRead = inStream.Read(bytes, 0, bufferSize)) > 0)
{
fileStream.Write(bytes, 0, bytesRead);
fileStream.Flush();
}
}
}
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么这比File.Copy执行速度慢得多?我能做些什么来提高性能吗?我是否只需要使用特殊逻辑来查看我是否从一个窗口位置复制到另一个窗口位置 - 在这种情况下我将只使用File.Copy而在其他情况下我将使用流?
请告诉我您的想法以及是否需要其他信息.我尝试了不同的缓冲区大小,似乎64k缓冲区大小对于我们的"小"文件来说是最佳的,256k +对于我们的"大"文件来说是一个更好的缓冲区大小 - 但无论哪种情况下它都比File.Copy执行得更糟糕( ).提前致谢!
这是我的代码。读取文件行的 WPF 按钮的事件处理程序:
private async void Button_OnClick(object sender, RoutedEventArgs e)
{
Button.Content = "Loading...";
var lines = await File.ReadAllLinesAsync(@"D:\temp.txt"); //Why blocking UI Thread???
Button.Content = "Show"; //Reset Button text
}
Run Code Online (Sandbox Code Playgroud)
我File.ReadAllLines()在 .NET Core 3.1 WPF App 中使用了异步版本的方法。
但它阻塞了 UI 线程!为什么?
更新:与@Theodor Zoulias 相同,我做了一个测试:
private async void Button_OnClick(object sender, RoutedEventArgs e)
{
Button.Content = "Loading...";
TextBox.Text = "";
var stopwatch = Stopwatch.StartNew();
var task = File.ReadAllLinesAsync(@"D:\temp.txt"); //Problem
var duration1 = stopwatch.ElapsedMilliseconds;
var isCompleted = task.IsCompleted;
stopwatch.Restart();
var lines …Run Code Online (Sandbox Code Playgroud) 我正在写一个异步将单独的文本行写入文件的方法。如果取消,它将删除创建的文件并跳出循环。
这是简化的代码,可以正常工作。。。我标记了2点,我不确定它们是如何处理的。我希望代码在任何情况下都不会阻塞线程。
public async Task<IErrorResult> WriteToFileAsync(string filePath,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
using var stream = new FileStream(filePath, FileMode.Create);
using var writer = new StreamWriter(stream, Encoding.UTF8);
foreach (var line in Lines)
{
if (cancellationToken.IsCancellationRequested)
{
//
// [1] close, delete and throw if cancelled
//
writer.Close();
stream.Close();
if (File.Exists(filePath))
File.Delete(filePath);
throw new OperationCanceledException();
}
// write to the stream
await writer.WriteLineAsync(line.ToString());
}
//
// [2] flush and let them dispose
//
await writer.FlushAsync();
await stream.FlushAsync();
// await stream.DisposeAsync();
return …Run Code Online (Sandbox Code Playgroud) c# ×3
asynchronous ×2
performance ×2
async-await ×1
buffer ×1
file-io ×1
filesystems ×1
java ×1
stream ×1
windows ×1
wpf ×1