3

无论我读取 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();
}

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

这可能是什么原因造成的?

4

2 回答 2

5

您需要写入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);
  }
}
于 2012-09-17T23:23:55.310 回答
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限制重写到输出的数据。

于 2012-09-17T23:22:48.970 回答