Xdocument加载后删除文件时出错



所以。。。。基本上,我需要创建一个将XML数据转换为CSV的小程序。我什么都做了。。。几乎

所有的代码都运行得很好,只有一个问题。一旦一切完成,我希望xml文件被删除。尽管它不会让我在Xdocument.Load行上抛出错误。

一旦文件被删除,Xdocument.Load就会告诉我它找不到文件,但一切都已完成,我不需要它来尝试加载已删除的文件。。。

以下是我的大部分代码:

static void Main()
{

using var watcher = new FileSystemWatcher(@"C:UsersStevenDocumentsXML");
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Changed += OnChanged;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
watcher.Renamed += OnRenamed;
watcher.Error += OnError;
watcher.Filter = "*.xml";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}

private static void OnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Changed)
{
return;
}
StringBuilder sb = new();
string delimiter = ",";
string path = $"{e.FullPath}";
XDocument loadInvoices = XDocument.Load(path);
string invoiceText = loadInvoices.ToString();
var invoice = XElement.Parse(invoiceText);
string supplierName = "";
string invoicePO = "";

sb.Append("Supplier" + delimiter);
foreach (var item in invoice.Descendants("Fields").Descendants("Field").ToList())
{
sb.Append(item.Attribute("Name").Value.Replace("é","e")+ delimiter);
}
sb.AppendLine();
foreach (var item in invoice.Descendants("Supplier").ToList())
{
supplierName = item.Element("Name").Value;
sb.Append(supplierName + delimiter);
}
foreach (var item in invoice.Descendants("Fields").Descendants("Field").ToList())
{
string temp = item.Attribute("Type").Value;
if (temp != "invoiceordernumber")
{               
sb.Append(item.Value + delimiter);
}
else
{
invoicePO = item.Value;
sb.Append(item.Value + delimiter);
}

}

StreamWriter sw = new StreamWriter(@"C:UsersStevenDocumentsXML"+ supplierName +"_PO#"+ invoicePO + ".csv");
sw.WriteLine(sb.ToString());
sw.Close();
loadInvoices = null;
File.Delete(path);

}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
Console.WriteLine("File " + e.FullPath + " started copying : " + DateTime.Now.ToString());
while (true)
{
try
{
FileStream fileStream = File.Open(e.FullPath, FileMode.Open, FileAccess.Read);
Console.WriteLine("File is copied : " + DateTime.Now.ToString());
fileStream.Close();

//there is the point when the file is completed copying .... now you should be able to access the file and process it.
return;
}
catch (IOException ioException) { }

}
}
private static void OnDeleted(object sender, FileSystemEventArgs e) =>
Console.WriteLine($"Deleted: {e.FullPath}");
private static void OnRenamed(object sender, RenamedEventArgs e)
{
Console.WriteLine($"Renamed:");
Console.WriteLine($"    Old: {e.OldFullPath}");
Console.WriteLine($"    New: {e.FullPath}");
}
private static void OnError(object sender, ErrorEventArgs e) =>
PrintException(e.GetException());
private static void PrintException(Exception? ex)
{
if (ex != null)
{
Console.WriteLine($"Message: {ex.Message}");
Console.WriteLine("Stacktrace:");
Console.WriteLine(ex.StackTrace);
Console.WriteLine();
PrintException(ex.InnerException);
}
}
}

请帮助:(

这看起来像是在循环中运行此代码或以其他方式导致代码在完成后重新运行所引起的问题。

我建议您尝试调试,看看那里发生了什么,以及为什么要重新运行它。

除此之外,最好在加载文件之前检查文件是否存在:

if (!File.Exists(path))
return;
XDocument loadInvoices = XDocument.Load(path);

这将检查文件是否存在,如果不存在,它将退出代码所在的任何函数,否则,它将继续。

这可能会解决您的问题,因为它将阻止代码打开已删除的文件。

FileWatcher将在您删除文件时触发一个更改事件,因此它将在文件消失后重新调用OnChanged事件处理程序。这就是加载操作失败的原因。

当您尝试将XML加载为建议的注释之一时,可以在其中放入if File.Exists(path),或者在删除后,从FileWatcher中删除OnChanged事件委托。

最新更新