我在ASP.NET MVC 4应用程序中使用log4net,我正在尝试从log4Net下载生成的日志文件。
我想用FileResult下载日志文件,例如:
[Authorize(Roles = "Admin")]
public FileResult DownloadUserInterfaceLog()
{
// Get the path of the log file
string path = (LogManager.GetCurrentLoggers()[0].Logger.Repository.GetAppenders()[0] as FileAppender).File;
// Get the file
byte[] fileBytes = System.IO.File.ReadAllBytes(path);
string fileName = "Log.txt";
// Return the expected file
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
我的问题是当我调用System.IO.File.ReadAllBytes(path);
时出现异常,导致日志文件已被其他进程使用。
我已经放<lockingModel value="log4net.Appender.FileAppender+MinimalLock" /> (which should release the file after any modification) in my Web.Config
但没有成功。
Web.Config中的log4Net配置开始:
<log4net>
<appender name="Appender-root" type="log4net.Appender.RollingFileAppender">
<lockingModel value="log4net.Appender.FileAppender+MinimalLock" />
<file value="Path..." />
<appendToFile value="true" />
答案 0 :(得分:2)
您需要在访问文件之前关闭Appender:
((FileAppender)LogManager.GetCurrentLoggers()[0].Logger.Repository.GetAppenders()[0]).Close()
答案 1 :(得分:2)
Here是一篇关于类似问题的文章。
File.ReadAllBytes()函数被编写为使用类似的调用 以下实例化FileStream:
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
请注意,FileShare被指定为Read。这意味着如果你有 另一段代码同时写入同一个文件,你 即使另一段代码创建了,也会出错 FileStream通过将共享模式指定为“ReadWrite”,如下所示:
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
解决方案是编写自己的自定义ReadAllBytes:
public static byte[] ReadAllBytes(String path)
{
byte[] bytes;
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
int index = 0;
long fileLength = fs.Length;
if (fileLength > Int32.MaxValue)
throw new IOException(“File too long”);
int count = (int)fileLength;
bytes = new byte[count];
while (count > 0)
{
int n = fs.Read(bytes, index, count);
if (n == 0)
throw new InvalidOperationException(“End of file reached before expected”);
index += n;
count -= n;
}
}
return bytes;
}