[英]Avoid Access Denied when writing to file
我使用以下方法登錄到文件
public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName)
{
FileInfo fileinfoMaster;
FileInfo fileinfoLog;
string fileName = string.Empty;
int tmpInt = 0;
filePathAndName = filePathAndName.ToLower();
while (true)
{
lock (LogDataContractToFileLock)
{
if (!_workingWithFiles.Contains(filePathAndName))
{
_workingWithFiles.Add(filePathAndName);
break;
}
}
Thread.Sleep(100);
}
try
{
#region Create XMLFile
if ((tmpInt = filePathAndName.LastIndexOf('.')) > 0)
fileName = filePathAndName.Remove(tmpInt, filePathAndName.Length - tmpInt);
else
fileName = filePathAndName;
fileinfoMaster = new FileInfo(fileName + ".xml");
fileinfoLog = new FileInfo(fileinfoMaster.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + ".log");
if ((fileinfoMaster.Exists && !fileinfoLog.Exists) ||
(!fileinfoMaster.Exists && fileinfoLog.Exists))
{
fileinfoMaster.Delete();
fileinfoLog.Delete();
}
//Se så att filen är 50 MB eller mindre annars arkivera
if (fileinfoMaster.Exists && fileinfoLog.Length > 52428800)
{
tmpInt = FileWriter.FileCount(fileinfoLog.DirectoryName, Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + "*.log");
fileinfoLog.MoveTo(Path.Combine(fileinfoLog.DirectoryName, Path.GetFileNameWithoutExtension(fileinfoLog.Name) + "_" + tmpInt.ToString() + ".log"));
CreateLogDataMasterFile(Path.Combine(fileinfoMaster.DirectoryName, Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + "_" + tmpInt.ToString() + ".xml"), fileinfoLog.Name);
fileinfoLog = new FileInfo(fileinfoMaster.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + ".log");
}
if (!fileinfoMaster.Exists)
{
DirectoryInfo info = new DirectoryInfo(fileinfoMaster.DirectoryName);
if (info.Exists == false)
info.Create();
CreateLogDataMasterFile(fileinfoMaster.FullName, Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + ".log");
}
#endregion
using (StreamWriter sw = File.AppendText(fileinfoMaster.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(fileinfoMaster.Name) + ".log"))
{
sw.Write(XMLStringToLog);
sw.Flush();
}
}
finally
{
lock (LogDataContractToFileLock)
{
_workingWithFiles.Remove(filePathAndName);
}
}
}
private static void CreateLogDataMasterFile(string filepathAndName, string dataFileName)
{
XmlTextWriter xmlWriter;
using (xmlWriter = new XmlTextWriter(filepathAndName, System.Text.Encoding.UTF8))
{
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteStartDocument();
xmlWriter.WriteDocType("DataLog", null, null, "<!ENTITY data SYSTEM \"" + dataFileName + "\">");
xmlWriter.WriteStartElement("root");
xmlWriter.WriteRaw("&data;");
xmlWriter.WriteEndElement();
xmlWriter.Flush();
}
}
幾個不同的線程可能同時寫入文件,並且在某些情況下,它們將寫入同一文件。 為了避免access denied, used by other process
問題,我已經實現了一些邏輯,如您所見。
問題是我仍然會access denied, used by other process
不時access denied, used by other process
。
我查看了諸如TextWriterTraceListener之類的跟蹤器中的構建,在這里可以看到以下注釋:
如果嘗試寫入正在使用或不可用的文件,則該文件名將由GUID自動添加前綴。
這樣看來,即使Microsoft對此也有問題? 是Windows問題嗎? 有什么辦法可以解決生成新文件的問題? 生成新文件將使文件中的數據流混亂很多!
是。 不要從多個線程寫入文件。 創建一個負責文件寫入的線程,並使其從ConcurrentQueue中讀取要寫入的內容。 任何需要寫的線程都應該將數據添加到隊列中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.