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

我对编码非常陌生,而且我正在编写一个应用程序,它会通过将毫秒附加到已经从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; } } 

每当我在我正在观看的文件夹中创建一个新文件时,它绝对没有任何意义。 起初我以为可能是因为我只有“OnCreated”方法,所以我将其复制到“OnChanged”方法(我不确定是否将现有文件复制到文件夹中,因为它被“创建”但是我没有运气)。

出于兴趣,如果我没有在filter中指定类型,我也会抛出一个exception,但是那时候压力要小得多。

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

您的代码存在一些问题。

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

其次,要接收Created事件,您应该包含NotifyFilters.FileName

但是,这对您没有多大帮助,因为文件在创建和更改的事件中被锁定,直到文件被复制,因此您将获得exception。 此外,您可能会收到多个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}"); } }