如何确定文件夹是否已完成复制c#
我有一个问题:如何确定文件夹是否已完成从一个位置到另一个位置的复制 目前,只要复制目录中的文件,我的FileSystemWatcher就会触发几个事件。不过,我想要的是,当成功复制该文件夹中的所有文件时触发一个事件。我现在的代码如下所示:如何确定文件夹是否已完成复制c#,c#,.net,directory,filesystemwatcher,C#,.net,Directory,Filesystemwatcher,我有一个问题:如何确定文件夹是否已完成从一个位置到另一个位置的复制 目前,只要复制目录中的文件,我的FileSystemWatcher就会触发几个事件。不过,我想要的是,当成功复制该文件夹中的所有文件时触发一个事件。我现在的代码如下所示: static void Main(string[] args) { String path = @"D:\Music"; FileSystemWatcher mWatcher = new FileSystemWatche
static void Main(string[] args)
{
String path = @"D:\Music";
FileSystemWatcher mWatcher = new FileSystemWatcher();
mWatcher.Path = path;
mWatcher.NotifyFilter = NotifyFilters.LastAccess;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.LastWrite;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.DirectoryName;
mWatcher.IncludeSubdirectories = true;
mWatcher.Created += new FileSystemEventHandler(mLastChange);
mWatcher.Changed += new FileSystemEventHandler(mLastChange);
mWatcher.EnableRaisingEvents = true;
Console.WriteLine("Watching path: " + path);
String exit;
while (true)
{
exit = Console.ReadLine();
if (exit == "exit")
break;
}
}
private static void mLastChange(Object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.ChangeType + " " + e.FullPath);
}
不幸的是,FileSystemWatcher不会告诉您文件何时完成写入。所以你的选择是
static void Main(string[] args)
{
Timer.Interval = 5000; // 5 seconds - change to whatever is appropriate
Timer.AutoReset = false;
Timer.Elapsed += TimeoutDone;
String path = @"D:\Music";
FileSystemWatcher mWatcher = new FileSystemWatcher();
mWatcher.Path = path;
mWatcher.NotifyFilter = NotifyFilters.LastAccess;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.LastWrite;
mWatcher.NotifyFilter = mWatcher.NotifyFilter | NotifyFilters.DirectoryName;
mWatcher.IncludeSubdirectories = true;
mWatcher.Created += new FileSystemEventHandler(mLastChange);
mWatcher.Changed += new FileSystemEventHandler(mLastChange);
mWatcher.EnableRaisingEvents = true;
Console.WriteLine("Watching path: " + path);
Timer.Start();
String exit;
while (true)
{
exit = Console.ReadLine();
if (exit == "exit")
break;
}
}
private static Timer Timer = new Timer();
private static void TimeoutDone(object source, ElapsedEventArgs e)
{
Console.WriteLine("Timer elapsed!");
}
private static void mLastChange(Object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.ChangeType + " " + e.FullPath);
if (Timer != null)
{
Timer.Stop();
Timer.Start();
}
}
它非常俗气,但在过去,我通过为FileSystemWatcher类创建自定义装饰器来处理这个问题。在内部,它创建一个FileSystemWatcher,并注册创建和更改的事件,包装它们,并在文件完成后抛出自己创建和更改的事件,类似于:
private void Watcher_Changed(Object sender, FileSystemEVentArgs e)
{
while (true)
{
FileStream stream;
try
{
stream = File.Open(e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
// If this succeeds, the file is finished
Changed();
}
catch (IOException)
{
}
finally
{
if (stream != null) stream.Close();
}
}
}
其中一些是从答案中得出的。实际上,不应该使用无限循环。您可能希望添加超时、在检查之间休眠等,但这是一般的想法。如果目标是本地文件夹,您可以使用文件系统筛选器驱动程序跟踪文件创建和文件关闭事件。知道以前创建的所有文件何时关闭将通知您复制已完成。我创建了一个Git repo,其中包含一个类,该类扩展了
FileSystemWatcher
,仅在复制完成时触发事件
下载并将其添加到您的项目中
然后将其用作正常的文件系统监视程序
,并在触发事件时进行监视
var fsw = new FileExamSystemWatcher(file);
fsw.EnableRaisingEvents = true;
// Add event handlers here
fsw.Created += fsw_Created;
不幸的是,没有现成的解决方案。但我设计了一个简单而棘手的解决方案来触发(复制完成)事件 你应该使用定时器
FileSystemWatcher fsw = new FileSystemWatcher();
string fullPath = "";
DateTime tempTime;
fsw.Path = @"C:\temp";
private void startwatching()
{
timer1.Start();
}
fsw.EnableRaisingEvents = true;
fsw.Created += Fsw_Created;
private void Fsw_Created(object sender, FileSystemEventArgs e)
{
tempTime = DateTime.Now.AddSeconds(-4);
fullPath = e.FullPath;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (fullPath!=string.Empty)
{
timer1.Stop();
if (tempTime >= Directory.GetLastAccessTime(fullPath))
{
DirectoryInfo di = new DirectoryInfo(fullPath);
listBox1.Items.Add("Folder " + di.Name + " finished copying");
fullPath = string.Empty;
}
else
{
tempTime = DateTime.Now;
}
timer1.Start();
}
}
注意网络位置,FSW不擅长监控这些位置。