在 C# 中使用 file.move 重命名新文件
Using file.move to rename new files in 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"方法中(我不确定将现有文件复制到文件夹中是否算作"created" 但我运气不好。
出于兴趣,如果我没有在过滤器中指定类型,我也会抛出一个异常,但目前这并不那么紧迫。
如果有人能指出我可能出错的地方,将不胜感激。
您的代码存在一些问题。
首先,您应该使用e.FullPath
而不是e.Name
,否则代码将尝试重命名当前目录中的文件,而不是监视目录中的文件。
其次,要接收 Created
事件,您应该包含 NotifyFilters.FileName
.
但是,这对您没有多大帮助,因为在复制文件之前,文件在创建和更改事件中被锁定,因此您会得到一个异常。此外,您可能会收到不止一个 Changed 事件(在我的测试中,无论文件大小如何,我总是收到两个,但在 Windows 或 .Net 框架的不同版本上可能会有所不同)。
要解决此问题,您可以使用计时器或线程来完成任务。这是一个使用 ThreadPool
线程的示例。每当 created 被触发时,您都会创建一个新线程。在线程中检查文件是否被锁定(尝试打开文件),当文件被解锁时,进行重命名。
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}");
}
}
我对编码很陌生,我正在编写一个将重命名文件的应用程序 通过将毫秒附加到已从 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"方法中(我不确定将现有文件复制到文件夹中是否算作"created" 但我运气不好。
出于兴趣,如果我没有在过滤器中指定类型,我也会抛出一个异常,但目前这并不那么紧迫。
如果有人能指出我可能出错的地方,将不胜感激。
您的代码存在一些问题。
首先,您应该使用e.FullPath
而不是e.Name
,否则代码将尝试重命名当前目录中的文件,而不是监视目录中的文件。
其次,要接收 Created
事件,您应该包含 NotifyFilters.FileName
.
但是,这对您没有多大帮助,因为在复制文件之前,文件在创建和更改事件中被锁定,因此您会得到一个异常。此外,您可能会收到不止一个 Changed 事件(在我的测试中,无论文件大小如何,我总是收到两个,但在 Windows 或 .Net 框架的不同版本上可能会有所不同)。
要解决此问题,您可以使用计时器或线程来完成任务。这是一个使用 ThreadPool
线程的示例。每当 created 被触发时,您都会创建一个新线程。在线程中检查文件是否被锁定(尝试打开文件),当文件被解锁时,进行重命名。
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}");
}
}