【问题标题】:How can I prevent my file from being used by another process?如何防止我的文件被另一个进程使用?
【发布时间】:2014-12-11 22:02:30
【问题描述】:

这是here 问题的续集,我想知道为什么我的流无法涉水。

利用回答另一个问题的一些猫的想法,我现在得到了这个代码:

private readonly FileStream _fileStream;
private readonly StreamWriter _streamWriter;

. . .

private ExceptionLoggingService()
{
    const int MAX_LINES_DESIRED = 1000;
    int linesInLogFile;

    string uriPath = GetExecutionFolder() + "\\Application.log";
    string logPath = new Uri(uriPath).LocalPath;
    _fileStream = File.Open(logPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
    StreamReader _streamReader = new StreamReader(_fileStream);
    List<String> logList = new List<String>();

    while (!_streamReader.EndOfStream)
    {
        logList.Add(_streamReader.ReadLine());
    }
    linesInLogFile = logList.Count;
    while (logList.Count > MAX_LINES_DESIRED)
    {
        logList.RemoveAt(0);
    }

    if (linesInLogFile > MAX_LINES_DESIRED)
    {
        _fileStream.Close();
        File.Delete(logPath);
        File.Create(logPath);
        _fileStream.Close(); // added this; did not help
        _fileStream.Dispose(); // this also did no good
        _fileStream = File.OpenWrite(logPath); // <= exception occurs here
    }

    _streamWriter = new StreamWriter(_fileStream);

    foreach (String s in logList)
    {
        _streamWriter.WriteLine(s);
    }
    _streamWriter.Flush(); // here is okay, right (as opposed to within the foreach loop)?
}

...但是在指示的 ("OpenWrite()") 行上,我得到以下异常(我在它上面添加了两行,首先调用 Close(),然后调用 Dispose(),但异常仍然是同样):

System.IO.IOException was unhandled
  _HResult=-2147024864
  _message=The process cannot access the file 'C:\HoldingTank\Sandbox\bin\Debug\Application.log' because it is being used by another process.

那么如果Close没有关闭_fileStream,而Dispose也没有dispose它,那该怎么办呢?

更新

这并没有严格回答我的问题,但受劳埃德评论的启发,它确实有效:

const int MAX_FILESIZE_ALLOWED = 20000;
string uriPath = GetExecutionFolder() + "\\Application.log";
string logPath = new Uri(uriPath).LocalPath;
FileInfo f = new FileInfo(logPath);
long fileLenInBytes = f.Length;
if (fileLenInBytes > MAX_FILESIZE_ALLOWED)
{
    File.Delete(logPath);
}
_fileStream = File.OpenWrite(logPath);
_streamWriter = new StreamWriter(_fileStream);

【问题讨论】:

  • 想法很简单。既然您想更新您的Application.log 文件(参考:stackoverflow.com/questions/27429716/…),请不要尝试同时读取和写入它。读取您的文件,关闭它,然后写入结果。这不是魔法。
  • 是的,这个想法很简单;暗黑破坏神在细节中。
  • 问了这么多题为什么还是不能解决是因为你的无能,而不是因为cmet或到目前为止发布的答案。例如。我认为我之前的评论是对您问题的确切答案。 (你知道如何实现它吗?然后阅读基本的 c# 教程。)
  • 也许是这样,但我脑力的不足我靠坚持来弥补。
  • @B.ClayShannon 实际上,根据之前评论的清晰度 - 看起来你两个都很好:)

标签: c# file-io process filestream


【解决方案1】:

您可以使用FileShare 枚举之一,例如:

_fileStream = File.Open(logPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);

您可以使用FileShare.None 锁定文件,如 MSDN 中所述:

拒绝共享当前文件。任何打开文件的请求(通过 此进程或其他进程)将失败,直到文件关闭。

但是,由于这是日志记录,我建议您使用 NLogLog4Net 之类的东西,而不是自己滚动,让它处理日志输出。

【讨论】:

  • 在第一个 File.Open()(不是 File.OpenWrite())上,对吧?
  • 您希望在第一个要锁定文件的实例上使用它。
  • 这是一个 Windows CE / Compact Framework 应用程序;我不认为在这种情况下这些是可用的(不过我通常喜欢 Log4Net)。
  • 好吧,文件有条件地被销毁,然后重新创建,所以我仍然不知道这里需要发生什么。锁定一个然后被破坏和复活的文件似乎没有意义。我尝试了该代码的所有组合(将它与我的第一个分配给 _fileStream 一起使用,我的第二个分配与两者一起使用,以及完整的 Close 和 Dispose 调用并被注释掉 - 在所有情况下我仍然得到一个 IO 异常。
  • 我认为在文件中阅读是一种浪费。为什么 MAX_LINES_DESIRED 而不是说最大日志大小?然后,您可以在采取行动之前检查文件大小。 BTW NLog 确实支持 Windows Mobile iirc。
猜你喜欢
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 2011-04-13
  • 2017-12-02
  • 2011-09-04
  • 1970-01-01
相关资源
最近更新 更多