Reputation: 1309
It does not matter if I read a TXT file or a XML file I always see "extra" info added into my file which is saved to disk. We first do the following:
FileStream fs = new FileStream(fileMoverFile.SourcePath, FileMode.Open, FileAccess.Read);
Then we assign fs
to a variable of type Stream
which we pass to the function below:
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();
}
When I open the file which was saved to disk, I see extra information which is basically some content of the same file being repeated with some other info which do not belong to the file. Very strange.
What could be causing this?
Upvotes: 3
Views: 3943
Reputation: 564851
You need to write bytesRead
bytes, not bufferSize
bytes:
int bytesRead = fileStream.Read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.Write(buffer, 0, bytesRead); // Change this here
Right now, when you reach the end of the input stream, you're potentially writing more data than you read in, which will cause "extra garbage" at the end of the file.
That being said, if your goal is just to copy the stream, you could just use Stream.CopyTo (provided you're in .NET 4+). This avoids the read/write loop entirely, and simplifies your code dramatically:
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);
}
}
Upvotes: 5
Reputation: 155648
You're not using your buffer properly. In the event that the call to fileStream.Read()
returns less than bufferSize
then your program still continues to read the rest of the buffer that would contain previously-read data.
Here's how you should do it:
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();
}
Note how I used using
and bytesRead
to limit the data rewritten to the output.
Upvotes: 1