I did not completely use your code but re-written a piece of code myself. There are two main differences between this code and your code.
I didn't customize FileOperations to inherit FileSystemWatcher but directly used FileSystemWatche because I don't really understand the role of some methods in FileOperations.
When the Created event is used, the file is moved to the target path as soon as it is created, and we have no time to rename it. This causes all files to use the default name, and the code will delete the file with the name already existing, so there will always be only one file with the default name in the target path.
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;
});
}
}
Update:
I build a new winform application, and then add a listview from the toolbox.
I made a small modification to the code, because when the monitored folder is the root directory of c, in fact, new files created in its subdirectories will also be monitored.
The previous code will have an error in handling this situation. I modified it slightly in the OnRenamed handler:
FileInfo fileInfo = new FileInfo(e.FullPath);
string TargetFile = Path.Combine(TargetPath, fileInfo.Name);
The current situation is as follows:
The file mentioned in the exception message is obviously not the *.txt file that we need to monitor. It is a file of Sql Server and contains transaction logs for Microsoft SQL Server relational database that record all completed and pending transactions since last checkpoint.
I am not sure why it was detected, but when I re-checked the program, I found a problem that I hadn't noticed before.
If we create a file but do not rename it, and then rename the previous file, the previous file will be written and moved.
I added a new field and used it like this:
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)
// ......
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.