2

The example from MSDN seems to read the whole file into memory. I don't want that. The file should be processed block by block. Therefore I tried to rewrite the example:

using (FromBase64Transform myTransform = new FromBase64Transform (FromBase64TransformMode.IgnoreWhiteSpaces)) {
    byte[] transformBuffer = new byte[myTransform.OutputBlockSize];

    using (FileStream inputFile = File.OpenRead("/path/to/file/47311.b64")) {
        using(FileStream outputFile = File.OpenWrite("/path/to/file/47311.jpg")){
            int bytesRead;
            byte[] inputBuffer = new byte[4096];
            while ((bytesRead = inputFile.Read (inputBuffer, 0, 4096)) > 0) {
                int bytesWritten = myTransform.TransformBlock (inputBuffer, 0, 4, transformBuffer, 0);
                outputFile.Write (transformBuffer, 0, bytesWritten);
            }

            myTransform.Clear ();
        }
    }
}

But the image can't be opened. What I'm doing wrong?

testing
  • 19,681
  • 50
  • 236
  • 417

2 Answers2

2

I believe this line is the bug:

int bytesWritten = myTransform.TransformBlock (inputBuffer, 0, 4, transformBuffer, 0);

You're transforming 4 bytes, regardless of how many bytes you've read. I suspect you want:

int bytesWritten = myTransform.TransformBlock (inputBuffer, 0, bytesRead, transformBuffer, 0);

You may need to change the size of transformBuffer though - if you're reading up to 4K of base64 data per iteration, you need up to 3K for plaintext data per iteration.

A simpler option, however, would probably be to create a CryptoStream using the transform, reading from the input stream, and then using Stream.CopyTo to write to a FileStream.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You are awesome. It now works with the adaptions you said. I'll have a look into `CryptoStream`. Thanks! – testing May 08 '15 at 10:32
2

Now I tried the CryptoStream as Jon mentioned:

using (FileStream inputFile = File.OpenRead ("/your/path/file.b64"))
using (FileStream outputFile = File.OpenWrite("/your/path/test.jpg"))
using (FromBase64Transform myTransform = new FromBase64Transform (FromBase64TransformMode.IgnoreWhiteSpaces))
using (CryptoStream cryptoStream = new CryptoStream(inputFile, myTransform, CryptoStreamMode.Read))
{
    cryptoStream.CopyTo (outputFile, 4096);
}

It works and it is simpler.

testing
  • 19,681
  • 50
  • 236
  • 417