我没有完全使用你的代码,而是自己重写了一段代码。此代码和您的代码之间有两个主要区别。
我没有自定义 FileOperations 来继承 FileSystemWatcher,而是直接使用 FileSystemWatche,因为我并不真正了解某些方法在 FileOperations 中的作用。
使用 Created 事件时,文件在创建后立即移动到目标路径,我们没有时间重命名它。这会导致所有文件都使用默认名称,并且代码将删除名称已存在的文件,因此目标路径中将始终只有一个具有默认名称的文件。
public partial class Form1 : Form
{
private string TargetPath = @"d:\test11\";
private bool IsNewFile = false;
private List<ListViewItem> myCache = new List<ListViewItem>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listView1.View = View.Details;
listView1.GridLines = true;
listView1.VirtualMode = true;
listView1.RetrieveVirtualItem += ListView1_RetrieveVirtualItem;
listView1.Columns.Add("Filename", 600);
var watcher = new FileSystemWatcher(@"d:\test");
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Created += OnCreated;
watcher.Renamed += OnRenamed;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
}
private void ListView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
if (myCache .Count>0)
{
e.Item = myCache[e.ItemIndex];
}
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
IsNewFile = true;
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
if (IsNewFile)
{
string TargetFile = Path.Combine(TargetPath, e.Name);
using (StreamWriter fileV = new System.IO.StreamWriter(e.FullPath))
{
foreach (var sfile in e.FullPath)
{
fileV.WriteLine(sfile);
}
}
if (File.Exists(TargetFile))
{
File.Delete(TargetFile);
}
//The File.Delete process may not end in time, causing File.Move to be abnormal, indicating that the file is being used.
Thread.S*leep(100);
File.Move(e.FullPath, TargetFile);
myCache.Add(new ListViewItem() { Text = TargetFile });
this.Invoke((MethodInvoker)delegate ()
{
listView1.VirtualListSize = myCache.Count;
});
}
}
更新:
我构建了一个新的 winform 应用程序,然后从工具箱中添加一个列表视图。
我对代码做了一个小的修改,因为当被监控的文件夹是 c 的根目录时,实际上在其子目录中创建的新文件也会被监控。
前面的代码在处理这种情况时会出错。我在 OnRenamed 处理程序中稍微修改了它:
FileInfo fileInfo = new FileInfo(e.FullPath);
string TargetFile = Path.Combine(TargetPath, fileInfo.Name);
目前情况如下:
异常消息中提到的文件显然不是我们需要监控的 *.txt 文件。它是 Sql Server 的文件,包含 Microsoft SQL Server 关系数据库的事务日志,这些日志记录了自上次检查点以来所有已完成和挂起的事务。
我不确定为什么会检测到它,但是当我重新检查程序时,我发现了一个我以前没有注意到的问题。
如果我们创建一个文件但不重命名它,然后重命名前一个文件,则将写入和移动前一个文件。
我添加了一个新字段并像这样使用它:
private string newFilePath;
private void OnCreated(object sender, FileSystemEventArgs e)
{
newFilePath = e.FullPath;
IsNewFile = true;
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
if (IsNewFile && e.OldFullPath == newFilePath)
// ......
如果回复有帮助,请点击“接受答案”并点赞。 注意:如果您想接收此线程的相关电子邮件通知,请按照我们文档中的步骤启用电子邮件通知。