FileStream将“额外”字符添加到TXT文件

时间:2012-09-17 23:20:04

标签: c# stream filestream

如果我读取TXT文件或XML文件并不重要,我总会在我的文件中看到“额外”信息保存到磁盘。我们首先做以下事情:

FileStream fs = new FileStream(fileMoverFile.SourcePath, FileMode.Open, FileAccess.Read);

然后我们将fs分配给Stream类型的变量,我们将其传递给下面的函数:

private void SaveToDisk(Stream fileStream, string saveToPath)
{
  if (!Directory.Exists(Path.GetDirectoryName(saveToPath)))
  {
    Directory.CreateDirectory(Path.GetDirectoryName(saveToPath));
  }
  FileStream outputStream = new FileInfo(saveToPath).OpenWrite();
  const int bufferSize = 1024;
  byte[] buffer = new byte[bufferSize];
  int bytesRead = fileStream.Read(buffer, 0, bufferSize);
  while (bytesRead > 0)
  {
    outputStream.Write(buffer, 0, bufferSize);
    bytesRead = fileStream.Read(buffer, 0, bufferSize);
  }
  outputStream.Close();
}

当我打开保存到磁盘的文件时,我看到了额外的信息,这些信息基本上是同一文件的某些内容被重复,其他信息不属于该文件。 很奇怪。

导致这种情况的原因是什么?

2 个答案:

答案 0 :(得分:4)

您需要编写bytesRead个字节,而不是bufferSize个字节:

int bytesRead = fileStream.Read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
    outputStream.Write(buffer, 0, bytesRead); // Change this here

现在,当你到达输入流的末尾时,你可能会写入比你读入的数据更多的数据,这会在文件的末尾造成“额外的垃圾”。

话虽这么说,如果您的目标只是复制流,您可以使用Stream.CopyTo(假设您使用的是.NET 4+)。这完全避免了读/写循环,并大大简化了代码:

private void SaveToDisk(Stream fileStream, string saveToPath)
{
  if (!Directory.Exists(Path.GetDirectoryName(saveToPath)))
  {
    Directory.CreateDirectory(Path.GetDirectoryName(saveToPath));
  }
  using(FileStream outputStream = new FileInfo(saveToPath).OpenWrite())
  {
      fileStream.CopyTo(outputStream);
  }
}

答案 1 :(得分:1)

您没有正确使用缓冲区。如果对fileStream.Read()的调用返回小于bufferSize,则程序仍会继续读取包含先前读取数据的其余缓冲区。

这是你应该怎么做的:

using(FileStream output = new FileStream( saveToPath, FileMode.Create, FileAccess.Write )) {

    Byte[] buffer = new Byte[ 32 * 1024 ]; // a 32KB-sized buffer is the most efficient
    Int32 bytesRead;

    while( (bytesRead = fileStream.Read( buffer, 0, buffer.Length ) ) > 0 ) {

        output.Write( buffer, 0, bytesRead );
    }
    output.Flush();
}

请注意我使用usingbytesRead来限制重写到输出的数据。