Inconsistent file size change while writing bytes from stream to a file

1.3k views Asked by At

I have a file with size 10124, I am adding a byte array, which has length 4 in the beginning of the file. After that the file size should become 10128, but as I write it to file, the size decreased to 22 bytes. I don't know where is the problem

public void AppendAllBytes(string path, byte[] bytes)
{
    var encryptedFile = new FileStream(path, FileMode.Open, FileAccess.Read);
    ////argument-checking here.
    Stream header = new MemoryStream(bytes);

    var result = new MemoryStream();
    header.CopyTo(result);
    encryptedFile.CopyTo(result);

    using (var writer = new StreamWriter(@"C:\\Users\\life.monkey\\Desktop\\B\\New folder (2)\\aaaaaaaaaaaaaaaaaaaaaaaaaaa.docx.aef"))
    {
        writer.Write(result);
    }
}

How can I write bytes to the file?

1

There are 1 answers

0
Ivaylo Slavov On

The issue seems to be caused by:

  • using a StreamWriter to write binary formatted data. The name does not inthuitively suggest this, but the StreamWriter class is suited for writing textual data.

  • passing an entire stream instead of the actual binary data. To obtain the bytes stored in a MemoryStream, use its convenient ToArray() method.

I suggest you the following code:

public void AppendAllBytes(string path, byte[] bytes)
{
    var fileName = @"C:\\Users\\life.monkey\\Desktop\\B\\New folder (2)\\aaaaaaaaaaaaaaaaaaaaaaaaaaa.docx.aef";

    using (var encryptedFile = new FileStream(path, FileMode.Open, FileAccess.Read))
    using (var writer = new BinaryWriter(File.Open(fileName, FileMode.Append)))
    using (var result = new MemoryStream())
    {
        encryptedFile.CopyTo(result);
        result.Flush(); // ensure header is entirely written.

        // write header directly, no need to put it in a memory stream
        writer.Write(bytes);
        writer.Flush(); // ensure the header is written to the result stream.
        writer.Write(result.ToArray());
        writer.Flush(); // ensure the encryptdFile is written to the result stream.
    }
}

The code above uses the BinaryWriter class which is better suited for binary data. It has a Write(byte[] bytes) method overload that is used above to write an entire array to the file. The code uses regular calls to the Flush() method that some may consider not needed, but these guarantee in general, that all the data written prior the call of the Flush() method is persisted within the stream.