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?
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
.
See more on this question at Stackoverflow