gpt4 book ai didi

c# - C#文件流在写/读操作完成之前不会阻塞

转载 作者:太空宇宙 更新时间:2023-11-03 18:16:51 25 4
gpt4 key购买 nike

我正在尝试编写一个将文件从一个位置复制到另一个位置并报告进度的类。我遇到的问题是,当应用程序运行时,进度会立即从0飙升到100%,但是文件仍在后台复制。

    public void Copy(string sourceFile, string destinationFile)
{
_stopWatch.Start();

_sourceStream = new FileStream(srcName, FileMode.Open);
_destinationStream = new FileStream(destName, FileMode.CreateNew);

read();
//On a 500mb file, execution will reach here in about a second.
}

private void read()
{
int i = _sourceStream.Read(_buffer, 0, bufferSize);

_completedBytes += i;

if (i != 0)
{
_destinationStream.Write(_buffer, 0, i);

TriggerProgressUpdate();

read();
}
}

private void TriggerProgressUpdate()
{
if (OnCopyProgress != null)
{
CopyProgressEventArgs arg = new CopyProgressEventArgs();
arg.CompleteBytes = _completedBytes;

if (_totalBytes == 0)
_totalBytes = new FileInfo(srcName).Length;

arg.TotalBytes = _totalBytes;

OnCopyProgress(this, arg);
}
}


似乎正在发生的事情是FileStream仅在OS中排队操作,而不是阻塞直到读取或写入完成。

有什么方法可以禁用此功能而不会造成巨大的性能损失?

PS。我正在使用测试源和目标变量,这就是为什么它们不匹配参数的原因。

谢谢
克雷格

最佳答案

我不认为它可以使读取操作排队...毕竟,您有一个字节数组,在Read调用后它将有一些数据-数据最好是正确的。可能只有正在缓冲的写操作。

您可以尝试定期在输出流上调用Flush ...我不知道Flush在各种缓存级别上会走多远,但它可能要等到实际写入数据后才能进行。编辑:如果您知道它是一个FileStream,您可以调用Flush(true),它将等待直到数据实际已写入磁盘。

请注意,您不应经常执行此操作,否则性能会受到严重影响。您需要在进度准确性的粒度与性能损失之间取得平衡,以进行更多控制,而不是让操作系统优化磁盘访问。

我担心您在这里使用递归-在一个非常大的文件上,您可能会毫无理由地感到栈溢出。 (CLR有时可以优化尾递归方法,但并非总是如此)。我建议您改用循环。国际海事组织,这也将更具可读性:

public void Copy()
{
int bytesRead;
while ((bytesRead = _sourceStream.Read(_buffer, 0, _buffer.Length)) > 0)
{
_destinationStream.Write(_buffer, 0, bytesRead);
_completedBytes += bytesRead;
TriggerProgressUpdate();
if (someAppropriateCondition)
{
_destinationStream.Flush();
}
}
}


希望您顺便处理一下流。我个人尽量避免使用可抛弃的成员变量。有什么原因不能只在 using语句中使用局部变量?

关于c# - C#文件流在写/读操作完成之前不会阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4966688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com