如果我读取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();
}
当我打开保存到磁盘的文件时,我看到了额外的信息,这些信息基本上是同一文件的某些内容被重复,其他信息不属于该文件。 很奇怪。
导致这种情况的原因是什么?
答案 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();
}
请注意我使用using
和bytesRead
来限制重写到输出的数据。