使用file.move重命名C#中的新文件

时间:2018-05-13 22:28:46

标签: c# filesystemwatcher

我对编码很陌生,我正在编写一个重命名文件的应用程序  通过将毫秒附加到已从MFD扫描的文件的现有文件名。 该文件夹是一个共享文件夹,重命名的文件应保留在其中,不得复制到其他位置。

通过大量搜索,我知道File.Move是我前进的方向,然而,我似乎无法让它发挥作用。

这是我的代码:

private void MonitorToggle_Click(object sender, EventArgs e)
    {
       // Create a new FileSystemWatcher object.
        FileSystemWatcher fsWatcher = new FileSystemWatcher();

        switch (MonitorToggle.Text)
        {
            // Start Monitoring…
            case startMonitoring:
                if (!FilePathField.Text.Equals(String.Empty))
                {
                    //Set the watched folder path equal to the file path variable
                    fsWatcher.Path = FilePathField.Text;

                    // Set Filter.
                    fsWatcher.Filter = (FileTypeField.Text.Equals(String.Empty))? "*.*" : FileTypeField.Text;

                    // Monitor files and subdirectories.
                    fsWatcher.IncludeSubdirectories = true;

                    // Monitor all changes specified in the NotifyFilters.
                    fsWatcher.NotifyFilter = NotifyFilters.LastWrite;

                    fsWatcher.EnableRaisingEvents = true;

                    // Raise Event handlers.
                    fsWatcher.Changed += new FileSystemEventHandler(OnChanged);
                    fsWatcher.Created += new FileSystemEventHandler(OnCreated);
                }
                else
                {
                    MessageBox.Show("Please select a folder to monitor.", "Warning",MessageBoxButtons.OK, MessageBoxIcon.Warning );
                }
                break;

            // Stop Monitoring…
            case stopMonitoring:
            default:

                fsWatcher.EnableRaisingEvents = false;
                fsWatcher = null;
                break;
        }

    }

    public void OnChanged (object sender, FileSystemEventArgs e)
    {
        FileInfo file = new FileInfo(e.Name);
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = file.Name;
        string newFile = string.Concat(fName, dateStamp);
        File.Move(fName,newFile);            
    }

    public void OnCreated(object sender, FileSystemEventArgs e)
    {
        FileInfo file = new FileInfo(e.Name);
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = file.Name;
        string newFile = string.Concat(fName, dateStamp);
        File.Move(fName, newFile);
    }

    private void BrowseButton_Click(object sender, EventArgs e)
    {
        // Create FolderBrowserDialog object.
        FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
        // Show a button to create a new folder.
        folderBrowserDialog.ShowNewFolderButton = true;
        DialogResult dialogResult = folderBrowserDialog.ShowDialog();
        // Get selected path from FolderBrowserDialog control.
        if (dialogResult == DialogResult.OK)
        {
            FilePathField.Text = folderBrowserDialog.SelectedPath;
            Environment.SpecialFolder root = folderBrowserDialog.RootFolder;
        }
    }

每当我在我正在观看的文件夹中创建一个新文件时,它什么都不做。起初我以为可能是因为我只有#34; OnCreated"方法,然后我将其复制到" OnChanged"方法(我不确定是否将现有文件复制到文件夹中,因为它是"已创建"但我没有运气)。

出于兴趣,如果我没有在过滤器中指定类型,我也会收到例外情况,但是那时候压力要小得多。

如果有人能提出任何可能出错的地方,我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。

首先,您应该使用e.FullPath而不是e.Name,否则代码会尝试重命名当前目录中的文件,而不是目录。

其次,要接收Created活动,您应该加入NotifyFilters.FileName

但是,这对您没有多大帮助,因为文件在创建和更改的事件中被锁定,直到文件被复制,因此您将获得异常。此外,您可能会收到多个Changed事件(在我的测试中,我总是收到两个,无论文件大小如何,但在不同版本的Windows或.Net框架上可能会有所不同。)

要解决此问题,您可以使用计时器或线程来完成任务。这是使用ThreadPool线程的示例。每当触发创建时,您都会创建一个新线程。在线程中,您检查文件是否被锁定(尝试打开文件),以及文件解锁时,进行重命名。

public class FileMon
{
    public static void Run()
    {
        FileSystemWatcher fsWatcher = new FileSystemWatcher();
        fsWatcher.Path = @"C:\Test\";        
        fsWatcher.Filter = "*.*" ;
        fsWatcher.IncludeSubdirectories = true;

        // Monitor all changes specified in the NotifyFilters.
        fsWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName ;

        fsWatcher.EnableRaisingEvents = true;

        // Raise Event handlers.
        fsWatcher.Changed += OnChanged;
        fsWatcher.Created += OnCreated;
        Console.WriteLine("[Enter] to end"); Console.ReadLine();
        fsWatcher.EnableRaisingEvents = false;
    }

    static void Worker(object state)
    {
        FileSystemEventArgs fsArgs = state as FileSystemEventArgs;
        bool done = false;
        FileInfo fi = new FileInfo(fsArgs.FullPath);

        do
        {
            try
            {
                using (File.Open(fsArgs.FullPath, FileMode.Open))
                {
                    done = true;
                }
            }
            catch
            {
                done = false;
            }
            Thread.Sleep(1000);
        } while (!done);
        Console.WriteLine("DOne");
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = fi.FullName;
        string newFile = fsArgs.FullPath + dateStamp;
        File.Move(fsArgs.FullPath, newFile);
    }

    private static void OnCreated(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine($"Created {e.ChangeType} : {e.Name}");
        ThreadPool.QueueUserWorkItem(Worker, e);
    }

    static void OnChanged(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine($"{e.ChangeType} : {e.FullPath}");
    }
}