我想要一个程序,该程序将不断监视文件夹中的文件,当文件出现在所述文件夹中时,该程序应等待文件可访问,然后将其移动到另一个文件夹。当前,文件尚未从文件夹“ test”移动到“ test2”。
我做到了,这样,当我单击“开始”按钮时,该窗体将最小化,并在后台运行并不断监视该文件夹。
private void btstart_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\test";
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Created += new FileSystemEventHandler(watcher_FileCreated);
watcher.EnableRaisingEvents = true;
}
public static bool Ready(string filename)
{
try
{
using (FileStream inputStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None))
return inputStream.Length > 0;
}
catch (Exception)
{
return false;
}
}
void watcher_FileCreated(object sender, FileSystemEventArgs e)
{
string path1 = @"C:\test";
string path2 = @"C:\test2";
string files = @"*.*";
string[] fileList = Directory.GetFiles(path1, files);
foreach (string file in fileList)
{
if (Ready(file) == true)
{
File.Move(path1, path2);
}
}
}
显然不是很明显,但是正在发生的事情是该文件没有从文件夹“ test”移动到文件夹“ test2”,没有抛出异常,没有错误,该文件未被任何人使用也不打开,权限也都正确设置,文件很简单,不会被移动
编辑解决方案:由于此主题中发布的答案,代码现在可以正常工作。 我自己添加了几件事,以便处理重复的异常。
folderlocationpath和folderdestinationpath变量是通过文件夹浏览器对话框读取的,因此用户可以自己选择2个文件夹位置 这是我目前拥有的:
string path1 = folderlocationpath;
string path2 = folderdestinationpath;
string files = @"*.*";
string[] fileList = Directory.GetFiles(path1, files);
foreach (string file in fileList)
{
if (Ready(file) == true)
try
{
File.Move(file, Path.Combine(path2, Path.GetFileName(file)));
}
catch (IOException) // for duplicate files an exception that deletes the file in destination folder and then moves the file from origin folder
{
string files2 = Path.GetFileName(file);
string[] fileList2 = Directory.GetFiles(path2, files2);
foreach (string file2 in fileList2)
File.Delete(file2);
File.Move(file, Path.Combine(path2, Path.GetFileName(file)));
}
}
答案 0 :(得分:1)
很容易看到答案。您将“文件夹路径”传递给File。将文件移入和移出路径。
File.Move(文件,path2 +“ \” + System.IO.Path.GetFileName(file));
在正文中添加了1个字符
答案 1 :(得分:0)
我考虑过对@BanMe答案进行编辑,但似乎最好在响应中包含更多内容,因为我可以有效地在他建议的修复程序中添加其他更改(现实,这一点非常重要)。我自己进行了测试。
这已经过测试,并且已在我的系统上验证为可以正常使用。为了使它更有效地工作,我还必须进行其他更改。它合并了Move
命令Path.Combine
的修复程序,但更重要的是,还向NotifyFilter
添加了FileName
。
您应该能够放置代码的这一部分,并且应该可以按照我的测试预期进行工作。
private void btstart_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\test";
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
watcher.Created += new FileSystemEventHandler(watcher_FileCreated);
watcher.EnableRaisingEvents = true;
}
public static bool Ready(string filename)
{
try
{
using (FileStream inputStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None))
return inputStream.Length > 0;
}
catch (Exception)
{
return false;
}
}
void watcher_FileCreated(object sender, FileSystemEventArgs e)
{
string path1 = @"C:\test";
string path2 = @"C:\test2";
string files = @"*.*";
string[] fileList = Directory.GetFiles(path1, files);
foreach (string file in fileList)
{
if (Ready(file) == true)
{
File.Move(file, Path.Combine(path2, System.IO.Path.GetFileName(file)));
}
}
}
为什么我们需要扩展NotifyFilters
?看一下this answer,我将在这里总结相关部分:
我也一直在这种行为上遇到麻烦。如果您单步执行代码(并且如果您查看MSDN文档,则会发现 NotifyFilter开始时的默认值为:
NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite
因此,当您说.NotifyFilter = NotifyFilters.CreationTime时,您将清除其他值,这说明了 行为。我不确定为什么NotifyFilters.CreationTime没有被捕获 新文件...看起来应该,应该吧!
看来,将NotifyFilter
隔离为LastWrite
只是忽略了FileSystemWatcher
的其他方面。添加FileName
为我解决了这个问题。
如果文件已经存在于C:\TEST2\
文件夹中,您可能仍然会遇到异常,但这是在File.Move
之前进行的非常简单的调整。