[英]Why does my file sometimes disappear in the process of reading from it or writing to it?
我有一個可以從文本文件中讀取內容的應用程序,以確定應該生成哪些報告。 它在大多數情況下都應能正常工作,但有時會刪除該程序,該程序會從中讀取/寫入其中的一個文本文件。 然后引發異常(“找不到文件”),並且進程停止。
這是一些相關的代碼。
首先,從文件中讀取:
List<String> delPerfRecords = ReadFileContents(DelPerfFile);
. . .
private static List<String> ReadFileContents(string fileName)
{
List<String> fileContents = new List<string>();
try
{
fileContents = File.ReadAllLines(fileName).ToList();
}
catch (Exception ex)
{
RoboReporterConstsAndUtils.HandleException(ex);
}
return fileContents;
}
然后,寫入文件-將文件中的記錄/行標記為已處理,以便下次檢查文件時不會重新生成相同的報告:
MarkAsProcessed(DelPerfFile, qrRecord);
. . .
private static void MarkAsProcessed(string fileToUpdate, string
qrRecord)
{
try
{
var fileContents = File.ReadAllLines(fileToUpdate).ToList();
for (int i = 0; i < fileContents.Count; i++)
{
if (fileContents[i] == qrRecord)
{
fileContents[i] = string.Format("{0}{1} {2}"
qrRecord, RoboReporterConstsAndUtils.COMPLETED_FLAG, DateTime.Now);
}
}
// Will this automatically overwrite the existing?
File.Delete(fileToUpdate);
File.WriteAllLines(fileToUpdate, fileContents);
}
catch (Exception ex)
{
RoboReporterConstsAndUtils.HandleException(ex);
}
}
因此,我確實刪除了該文件,但立即將其替換:
File.Delete(fileToUpdate);
File.WriteAllLines(fileToUpdate, fileContents);
正在讀取的文件具有以下內容:
Opas,20170110,20161127,20161231-COMPLETED 1/10/2017 12:33:27 AM
Opas,20170209,20170101,20170128-COMPLETED 2/9/2017 11:26:04 AM
Opas,20170309,20170129,20170225-COMPLETED
Opas,20170409,20170226,20170401
如果“ -COMPLETED”出現在記錄/行/行的末尾,則將被忽略-將不被處理。
同樣,如果第二個元素(在索引1處)是將來的日期,則將不會對其進行處理(尚未)。
因此,對於上面顯示的這些示例,前三個示例已經完成,隨后將被忽略。 直到2017年4月9日或之后,第四個數據才會生效(屆時將檢索最后兩個日期的數據范圍內的數據)。
為什么有時刪除文件? 我該怎么做才能防止它發生?
如果有幫助,在更多情況下,邏輯如下:
internal static string GenerateAndSaveDelPerfReports()
{
string allUnitsProcessed = String.Empty;
bool success = false;
try
{
List<String> delPerfRecords = ReadFileContents(DelPerfFile);
List<QueuedReports> qrList = new List<QueuedReports>();
foreach (string qrRecord in delPerfRecords)
{
var qr = ConvertCRVRecordToQueuedReport(qrRecord);
// Rows that have already been processed return null
if (null == qr) continue;
// If the report has not yet been run, and it is due, add i
to the list
if (qr.DateToGenerate <= DateTime.Today)
{
var unit = qr.Unit;
qrList.Add(qr);
MarkAsProcessed(DelPerfFile, qrRecord);
if (String.IsNullOrWhiteSpace(allUnitsProcessed))
{
allUnitsProcessed = unit;
}
else if (!allUnitsProcessed.Contains(unit))
{
allUnitsProcessed = allUnitsProcessed + " and "
unit;
}
}
}
foreach (QueuedReports qrs in qrList)
{
GenerateAndSaveDelPerfReport(qrs);
success = true;
}
}
catch
{
success = false;
}
if (success)
{
return String.Format("Delivery Performance report[s] generate
for {0} by RoboReporter2017", allUnitsProcessed);
}
return String.Empty;
}
我如何牢記此代碼,以防止文件定期被破壞?
我真的不能測試,因為問題很少發生,但是我想知道在File.Delete()和File.WriteAllLines()之間添加“暫停”是否可以解決問題?
我不太確定問題的答案是什么,因此我不會將其添加為答案,但是我的猜測是File.Delete()和File.WriteAllLines()在一起的距離太近,因此有時在文件的舊副本和新副本上都發生刪除。
如果是這樣,兩個調用之間的暫停可能會在99.42%的時間內解決問題,但是從我在這里發現的情況來看,似乎File.Delete()仍然是多余的/多余的,因此我對File.Delete進行了測試()進行了評論,並且效果很好; 因此,我現在沒有接到偶爾出現問題的電話。 我希望能解決這個問題。
// Will this automatically overwrite the existing?
File.Delete(fileToUpdate);
File.WriteAllLines(fileToUpdate, fileContents);
我只需要向WriteAllLines()
添加一個額外的參數(該參數可以默認為false
)來告訴該函數以覆蓋模式打開文件,然后根本不調用File.Delete()
。
您當前是否檢查打開的文件的返回值?
更新 :好的,看來WriteAllLines()
是.Net Framework函數,因此無法更改,因此我刪除了此答案。 但是,現在這已顯示在評論中,作為另一個論壇上的建議解決方案:
“只要使用File.WriteAllText之類的文件,如果文件存在,則數據將被覆蓋,如果文件不存在,則將創建它。”
這正是我的意思(認為WriteAllLines()
是用戶定義的函數),因為過去我也遇到過類似的問題。
因此,類似的解決方案可以解決一些棘手的問題(而不是刪除/快速重新打開,而只是覆蓋文件)-減少OS的工作量,並可能減少文件/磁盤碎片。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.