如this答案中所述:
我正在使用FileSystemWatcher
检测目录更改,然后读取文件内容并将其插入数据库。
这是我的代码:
private FileSystemWatcher _watcher;
public MainWindow()
{
try
{
InitializeComponent();
GetFiles();
//Task.Factory.StartNew(() => GetFiles())
// .ContinueWith(task =>
// {
// }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
catch(Exception ex)
{
//..
}
}
public bool GetFiles()
{
_watcher = new FileSystemWatcher(Globals.iniFilesPath, "*.ini");
_watcher.Created += FileCreated;
_watcher.IncludeSubdirectories = false;
_watcher.EnableRaisingEvents = true;
return true;
}
private void FileCreated(object sender, FileSystemEventArgs e)
{
try
{
string fileName = Path.GetFileNameWithoutExtension(e.FullPath);
if (!String.IsNullOrEmpty(fileName))
{
string[] content = File.ReadAllLines(e.FullPath);
string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();
ChargingStationFile csf = new Product
{
Quantity = Convert.ToDecimal(newStringArray[1]),
Amount = Convert.ToDecimal(newStringArray[2]),
Price = Convert.ToDecimal(newStringArray[3]),
FileName = fileName
};
ProductController.Instance.Save(csf);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
如果我使用CTRL + F5运行此代码,则收到此消息:
但是如果我使用F5
](调试模式),则会收到此错误,并且不会收到有关无法访问进程的错误,并且成功保存了项目。这真让我感到困惑。这是我第一次使用FileSystemWatcher,显然这里确实有问题。.
P.S,我发现此行引起异常:
string[] content = File.ReadAllLines(e.FullPath);
怎么来?
谢谢你们
欢呼声
我正在使用FileSystemWatcher来检测目录更改,然后读取文件内容并将其插入数据库。这是我的代码:private FileSystemWatcher _watcher;公共MainWindow(){...
如this答案中所述:
最有可能在这里发生的是FileCreated事件是被提出并尝试在之前处理文件完全写入磁盘。
因此,您需要等待文件复制完成。根据this other answer:
从FileSystemWatcher的文档中:
一旦创建文件,就会引发OnCreated事件。如果一个文件被复制或转移到监视的目录中,即OnCreated事件将立即引发,然后是一个或多个OnChanged事件。
因此,针对您的情况的解决方法是创建一个字符串列表,其中包含在Created方法处理程序中无法读取的文件的路径,并在FileSystemWatcher的Changed事件中重新处理这些路径(请阅读代码中的注释):
public partial class MainWindow : Window {
private FileSystemWatcher _watcher;
public MainWindow() {
try {
InitializeComponent();
GetFiles();
} catch (Exception ex) {
MessageBox.Show($"Exception: {ex.Message}");
}
}
private bool GetFiles() {
_watcher = new FileSystemWatcher(@"C:\TestFolder", "*.ini");
_watcher.Created += FileCreated;
_watcher.Changed += FileChanged; // add this.
_watcher.IncludeSubdirectories = false;
_watcher.EnableRaisingEvents = true;
return true;
}
// this field is new, and contains the paths of the files that could not be read in the Created method handler.
private readonly IList<string> _waitingForClose = new List<string>();
private void FileChanged(object sender, FileSystemEventArgs e) {
if (_waitingForClose.Contains(e.FullPath)) {
try {
string[] content = File.ReadAllLines(e.FullPath);
string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();
MessageBox.Show($"On FileChanged: {string.Join(" --- ", newStringArray)}");
// Again, process the data from the file to saving in the database.
// removing the path, so as not to reprocess the file..
_waitingForClose.Remove(e.FullPath);
} catch (Exception ex) {
MessageBox.Show($"Exception on FileChanged: {ex.Message} - {e.FullPath}");
}
}
}
private void FileCreated(object sender, FileSystemEventArgs e) {
try {
string fileName = Path.GetFileNameWithoutExtension(e.FullPath);
if (!String.IsNullOrEmpty(fileName)) {
string[] content = File.ReadAllLines(e.FullPath);
string[] newStringArray = content.Select(s => s.Substring(s.LastIndexOf('=') + 1)).ToArray();
MessageBox.Show($"On FileCreated: {string.Join(" --- ", newStringArray)}");
// process the data from the file to saving in the database.
}
} catch (Exception ex) {
// if the method fails, add the path to the _waitingForClose variable
_waitingForClose.Add(e.FullPath);
//MessageBox.Show($"Exception on FIleCreated: {ex.Message} - {e.FullPath}");
}
}
}
如this答案中所述: