C# 打开、锁定、截断和写入文件

C# 打开、锁定、截断和写入文件,c#,.net,C#,.net,我试图复制Excel在打开和编辑文件时的行为,即: 文件已打开并锁定以进行独占写入访问 允许其他用户读取该文件 我使用以下代码打开文件,阅读并准备稍后编写: _fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); _fileReader = new StreamReader(_fileStream); _fileWriter = new StreamWriter(

我试图复制Excel在打开和编辑文件时的行为,即:

  • 文件已打开并锁定以进行独占写入访问
  • 允许其他用户读取该文件
我使用以下代码打开文件,阅读并准备稍后编写:

_fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
_fileReader = new StreamReader(_fileStream);
_fileWriter = new StreamWriter(_fileStream);
var contents = _fileReader.ReadToEnd();
(在实现IDisposable并处理流的类中)

除了一个问题外,它显然工作正常,稍后我使用以下代码保存时出现了一个问题:

_fileWriter.BaseStream.Seek(0, SeekOrigin.Begin);
_fileWriter.Write(content);
_fileWriter.Flush();
问题是我需要在保存之前截断文件,而上面的内容只会覆盖。如果新内容比加载的内容短,则由于部分旧内容,我最终会得到一个坏文件

如何在写入(而不是读取)之前截断文件流


有没有比我现在做的更好的方法来独占访问该文件?

我不知道为什么直到现在才想到这一点,但我在System.IO.file的源代码中找到了答案:

[SecurityCritical]
private static void InternalWriteAllText(
  string path,
  string contents,
  Encoding encoding,
  bool checkHost)
{
  using (StreamWriter streamWriter = new StreamWriter(path, false, encoding, 1024, checkHost))
    streamWriter.Write(contents);
}
我没有意识到我可以安全地打开文件进行写入,不是从现有的文件流,而是通过指定路径。这允许我将
append
设置为false

编辑:

在这个答案中可以找到一个更简单的解决方案:


写之前只需调用SetLength(0)。

@GSerg:谢谢。我找到了另一种方法,但SetLength是一个更简单的选项,因此我将用它替换我的代码。请注意,您不能在多个StreamReader/StreamWriter实例之间共享文件流。FileShare.xxx选项控制如何对同一文件使用多个句柄/文件流。@DavidBrowne Microsoft:Hm。。事实上,我本以为会是这样,但我还没有遇到这样做的不利影响。我应该看到什么样的问题,因为它似乎工作良好?然后,我如何锁定一个文件以便在其他地方写入,同时又允许我自己的应用程序写入它呢?读卡器和写卡器都有内部缓冲区,并且希望FileStream位置不会在他们不知道的情况下更改。FileStream只有一个位置,下一次读取或写入将在该位置进行。@DavidBrowne Microsoft:啊,非常感谢。我没有看到它的原因是因为我只使用了一次阅读器。我将重构代码,以防将来发生更改。