[英]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.