【发布时间】:2020-02-01 00:12:11
【问题描述】:
我正在尝试将文件从一个目录移动到另一个目录,同时在我的 WPF 应用程序中看到一个进度条。
移动操作非常慢,我找不到让它更快的解决方案(测试移动 38 Mb 的速度是 2:30 分钟)但我不知道如何有效地移动它。我现在的移动方式有效,但效率极低。
public delegate void ProgressChangeDelegate(double percentage);
public delegate void CompleteDelegate();
class FileMover
{
public string SourceFilePath { get; set; }
public string DestFilePath { get; set; }
public event ProgressChangeDelegate OnProgressChanged;
public event CompleteDelegate OnComplete;
public FileMover(string Source, string Dest)
{
SourceFilePath = Source;
DestFilePath = Dest;
OnProgressChanged += delegate { };
OnComplete += delegate { };
}
public void Copy()
{
byte[] buffer = new byte[1024 * 1024]; // 1MB buffer
using (FileStream source = new FileStream(SourceFilePath, FileMode.Open, FileAccess.Read))
{
long fileLength = source.Length;
using (FileStream dest = new FileStream(DestFilePath, FileMode.CreateNew, FileAccess.Write))
{
long totalBytes = 0;
int currentBlockSize = 0;
while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
{
totalBytes += currentBlockSize;
double percentage = (double) totalBytes * 100.0 / fileLength;
dest.Write(buffer, 0, currentBlockSize);
OnProgressChanged(percentage);
}
}
}
OnComplete();
}
}
private async void MoveFile(string source, string outDir)
{
if (!string.IsNullOrEmpty(outDir) && !string.IsNullOrEmpty(source))
{
//InputButtonText.Text = "Please be patient while we move your file.";
//Task.Run(() => { new FileInfo(source).MoveTo(Path.Combine(outDir, Path.GetFileName(source))); }).GetAwaiter().OnCompleted(
// () =>
// {
// OutputScanned.ItemsSource = null;
// InputButtonText.Text = "Click to select a file";
// });
var mover = new FileMover(source, Path.Combine(outDir, Path.GetFileName(source)));
await Task.Run(() => { mover.Copy(); });
mover.OnProgressChanged += percentage =>
{
MoveProgress.Value = percentage;
InputButtonText.Text = percentage.ToString();
};
mover.OnComplete += () => { File.Delete(source); };
}
}
【问题讨论】:
-
您似乎遇到了一些问题,您在这里具体寻求什么帮助?
-
您需要将问题分解为单独的问题。一次专注于一个,为每个人提供良好的minimal reproducible example,以便人们可以提供帮助。也就是说,您不应该通过显式复制来移动文件。请改用
System.IO.File.Move()方法。只要文件在同一卷内移动,此操作就会非常快速且与文件大小无关。如果您尝试跨卷移动,文件将被复制而不是移动(如果您需要,您必须自己删除源),但该操作仍将有效地完成。 -
@PeterDuniho 如果他们选择使用
System.IO.File.Move(),你对想要展示这一举动的进展的 OP 有什么建议? -
@Çöđěxěŕ:对于同一卷内的移动,完全不需要进度条。如果他们关心跨卷案例并且仍然想要一个进度条,还有其他选择,包括自己实施副本,但首先他们需要先解决他们需要帮助的问题。
-
我想首先解决的确切问题是,在保持某种进度跟踪器的同时复制速度相当慢。我现有的代码显示了我尝试过的内容。但是,如果需要,可以更改任何内容以获得更好的结果。我将编辑我的帖子,所以我只问一个问题。
标签: c# wpf file-management