-3

我想要一个程序,该程序将不断监视文件夹中的文件,当文件出现在所述文件夹中时,程序应等待文件可访问,然后将所述文件移动到另一个文件夹。目前这些文件没有从文件夹“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)));
                    }
            }
4

2 回答 2

0

答案很明显。您将文件夹路径传递给 File.Move 在文件输入和文件输出路径中。

File.Move(file, path2 + "\" + System.IO.Path.GetFileName(file));

在正文中添加了 1 个字符

于 2019-01-22T15:15:55.393 回答
0

我考虑对@BanMe 答案进行编辑,但似乎最好在响应中包含更多内容,因为我会有效地为他建议的修复添加额外的更改(实际上,这是非常重要)经过我自己的测试。

这已经过测试,并且经过验证可以在我的系统上运行。为了让它更有效地工作,我必须进行一项额外的更改。Move它包含了对命令的修复,Path.Combine但更重要的是还添加了一个NotifyFilterto 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?看看这个答案,我将在这里总结相关部分:

这种行为我也遇到了麻烦。如果您单步执行代码(并且如果您查看 MSDN 文档,您会发现 NotifyFilter 以默认值开始:

NotifyFilters.文件名 | NotifyFilters.DirectoryName | NotifyFilters.LastWrite

因此,当您说 .NotifyFilter = NotifyFilters.CreationTime 时,您正在消除那些其他值,这解释了行为上的差异。我不确定为什么 NotifyFilters.CreationTime 没有捕捉到新文件......似乎应该,不应该!

看来您将 隔离NotifyFilter为只是LastWrite忽略了FileSystemWatcher. 添加FileName为我解决了这个问题。

如果文件夹中已经存在文件,您可能仍然会遇到异常,但这是在您必须C:\TEST2\之前进行的非常简单的调整。File.Move

于 2019-01-24T17:55:16.047 回答