One Byte Missing After Using FileStream

T

Terry

In the code below, I open a file using filestream, copy it to a byte
array, and the write that array out to a new file. But when I check
the size of the original file and the new file, the new file has one
less byte than the original file (although the file itself still works
fine). I was hoping someone could explain what is going on (why is
there a byte missing, and what might that byte be).

string originalFile = @"C:\MP3Test\Original.mp3";
string copiedFile = @"C:\MP3Test\Copied.mp3";

// Read file into byte array
FileStream fs1 = new FileStream(originalFile, FileMode.OpenOrCreate,
FileAccess.Read);
byte[] mp3ByteArray = new byte[fs1.Length];
fs1.Read(mp3ByteArray, 0, System.Convert.ToInt32(fs1.Length));
fs1.Close();

// Write same byte array to new file
int arraySize = new int();
arraySize = mp3ByteArray.GetUpperBound(0);
FileStream fs2 = new FileStream(copiedFile, FileMode.OpenOrCreate,
FileAccess.Write);
fs2.Write(mp3ByteArray, 0, arraySize);
fs2.Close();

// Compare size of original an new file
FileInfo fileInfo1 = new FileInfo(originalFile);
FileInfo fileInfo2 = new FileInfo(copiedFile);

Console.WriteLine("Size of original file: " +
fileInfo1.Length.ToString());
// output====> 20629 bytes
Console.WriteLine("Size of copied file: " +
fileInfo2.Length.ToString());
// output====> 20628 bytes. One byte less than original file.

Thanks,

Terry
 
N

Nicholas Paldino [.NET/C# MVP]

Terry,

The reason you are getting this is because you are using a call to
GetUpperBound(0) on the array. This will return the index of the last
element in the array, which, in a zero-based array, turns out to be the
length - 1.

You can just do this:

int arraySize = mp3ByteArray.Length;

And it will work out fine.

Hope this helps.
 
J

Jon Skeet [C# MVP]

kids_pro said:
I am having the similiar problem.
But the different between the original file and the copy one is alot more.

int bufferSize = 102400;
byte[] read = new byte[bufferSize];

Stream fs = new
FileStream("E:\\anders_hejlsberg_linq_2005.wmv",FileMode.Open);

Stream fs2 = new
FileStream("D:\\anders_hejlsberg_linq_2005.wmv",FileMode.Create);

int chunk=0;
while((chunk=fs.Read(read,0,bufferSize))>0){
if(chunk < bufferSize){

/* truncate the byte it should reach end of file */
byte[] finalByte = new byte[chunk];
Array.Copy(read,finalByte,chunk);
fs.Write(finalByte,0,chunk);
}else{
fs2.Write(read,0,bufferSize);
}

read = new byte[bufferSize];
}
fs.Close();
fs2.Close();

Please refer to attach screenshot for the size different.
Why the size is different? Have I done any mistakes?

Well, I'm not sure why you're copying the array in the case where you
haven't read the whole file in one go - just use
fs2.Write(read, 0, chunk)

However, the error in your program is that by introducing the extra
complexity, you've got your other Write call to the wrong stream -
you're writing to the stream you've been reading from!

Note that you should also use "using" statements to make sure that your
FileStreams get closed even if an exception is thrown.
 
T

Terry

Thanks for the insights Nicholas and Jon. I'll spend some more time
studying this code and your responses so I understand it better.

This code was extracted from two methods I created to save .mp3's to a
database, and then write them out to a file again. I uncovered the
error when I wrote a unit test to compare the file before and after
saving to the database.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top