-3

Why does the code below not produce an identical output file to the input file?

The idea is to buffer a part of the file in and write it out from a smaller buffer (this is a small program reproducing an error in a larger project where I am streaming a file). When these files are checked in a hex editor comparison tool the output file differs somewhat.

fsIn = new FileStream("c:\\wmvs\\Wildlife.wmv", FileMode.Open, FileAccess.Read);
        fsOut = new FileStream("c:\\Users\\public\\documents\\compare\\out.wmv",      FileMode.Create, FileAccess.Write);

        bData = new byte[fsIn.Length / 10];
        bOut = new byte[524288];

        fsIn.Read(bData, 0, bData.Length);

        bool bGo = true;

        while (bGo)
        {
            if (nWrittenOut == bData.Length)
            {
                fsIn.Read(bData, 0, bData.Length);
            }

            if (nWrittenOut + bOut.Length >= bData.Length)
            {
                Array.Clear(bOut, 0, bOut.Length);

                int nWhatsLeft = bData.Length - nWrittenOut;
                Array.Copy(bData, nWrittenOut, bOut, 0, nWhatsLeft);

                fsIn.Read(bData, 0, bData.Length);
                nWrittenOut = 0;
                int nBufPos = nWhatsLeft;

                nWhatsLeft = bOut.Length - nWhatsLeft;
                Array.Copy(bData, nWrittenOut, bOut, nBufPos, nWhatsLeft);
                nWrittenOut += bOut.Length;

            }
            else
            {
                Array.Copy(bData, nWrittenOut, bOut, 0, bOut.Length);
                nWrittenOut += bOut.Length;
            }

            fsOut.Write(bOut, 0, bOut.Length);
            fsOut.Flush();

            if (fsOut.Position >= fsIn.Length)
                bGo = false;
        }

    }

I have tried all the below answers and nothing works. It must be my logic in the code. However I cannot see the problem ???? It seems I am missing a whole chunk in the output file eqivalent to the length of bOut.

Stewart Stoakes
  • 797
  • 1
  • 8
  • 13
  • 1
    If the goal is to copy a file I would use any of the copy mechanisms available.. I think there's like a File.Copy If it's to read in a stream and write out another stream, then I am baffled as to the lot of code you have in here.. – Jimmy Hoffa Aug 06 '10 at 19:46
  • 1
    A more descriptive question title will probably yield a lot more answers. – Ignacio Aug 06 '10 at 19:47
  • Describing how that data is off would help. Have the new-lines been changed? Zero characters written into the file? etc. Be specific, and as for your question title, it is terribly bad. This is not your personal forum. – Heath Hunnicutt Aug 06 '10 at 19:51
  • 1
    Perhaps it would also help if you give examples of how the hex comparisons differ... – Ates Goral Aug 06 '10 at 19:54
  • 3
    Research the `using` statement for your first two lines to guarantee closure of the files and release of the associated resources. – Jesse C. Slicer Aug 06 '10 at 19:56
  • OK I am using Stream instead of FileStream and using BinaryReader and writer. On checking the return values of fsIn.Read() I found that Im only reading in 6 bytes in the second If statement inside the loop. I can simply correct this by reading again until I get the original length I requested, however I would like to understand why Im only getting 6 bytes as opposed to bData.Length. I thought that using BinaryReader and Stream instead would stop any characters stopping the read from working as suggested by others in their answers. Sorry for the question title but am new here.... – Stewart Stoakes Aug 06 '10 at 20:10
  • I have tried all the below answers and nothing works. It must be my logic in the code. However I cannot see the problem ???? It seems I am missing a whole chunk in the output file eqivalent to the length of bOut. – Stewart Stoakes Aug 06 '10 at 21:34

5 Answers5

2

I don't know what you're doing, but why don't you try this, it's likely that reading and writing through a FileStream might not be encoding agnostic, so stick with a stream and just pass bytes along:

using (Stream inStream = File.Open(inFilePath, FileMode.Open))
{
    using (Stream outStream = File.Create(outFilePath))
    {
        while (inStream.Position < inStream.Length)
        {
            outStream.WriteByte((byte)inStream.ReadByte());
        }
    }
}
Jimmy Hoffa
  • 5,909
  • 30
  • 53
  • 1
    This solution is great if you want to watch the individual bytes crawl from a to b. In other words: It's slow as hell. Better use http://msdn.microsoft.com/en-us/library/dd782932.aspx or http://stackoverflow.com/questions/230128 -- or maybe even just http://msdn.microsoft.com/en-us/library/c6cfw35a.aspx – dtb Aug 06 '10 at 19:58
  • 1
    @dtb: Just trying to keep the example as simple as possible for the poster, he can figure out to use a set size buffer after he gets it working to begin with I figure. And the File.Copy I already suggested in comment above.. – Jimmy Hoffa Aug 06 '10 at 20:01
  • 3
    @dtb, Note the overload of `.CopyTo()` which allows for a user-specified buffer size. – Jesse C. Slicer Aug 06 '10 at 21:23
1

it's probably read/writing in Text mode, so that any 0x0A in encounters in the binary file is being converted to a CR/LF.

James Curran
  • 101,701
  • 37
  • 181
  • 258
1

You will need to use BinaryReader and BinaryWriter to avoid the Environment.NewLine translation that you are being "provided."

Heath Hunnicutt
  • 18,667
  • 3
  • 39
  • 62
0

You need to check the return value of your fsIn.Read method. The Read method will not always read the number of bytes that you requested. If you are seeing extra "0" bytes in the results then this is probably the cause.

David
  • 34,223
  • 3
  • 62
  • 80
0

Why are you not checking return value of fsIn.Read()? I have no (developer) experience with Windows platform, but can you always be sure that exactly this number of bytes will be read? What about the end of file? :)

Messa
  • 24,321
  • 6
  • 68
  • 92