Base64 Encoding a Large File


#1

I’m currently struggling to find the proper way to convert a large file (~50-100mb) to a Base64 string. I currently have:

    // Get the file from the temp directory
    const File largeFile (File::getSpecialLocation (File::tempDirectory)
                     .getChildFile ("AudioRecording.wav"));
    // send input stream to Base64::toBase64
    String b64 = Base64::toBase64(largeFile.createInputStream(), largeFile.getSize());

However this is writing each chunk of the stream into b64 resulting in a lot of repeated data What would be the proper way to handle this flow?

Thanks!
Tomek


#2

try this:

const File largeFile (File::getSpecialLocation (File::tempDirectory)
                 .getChildFile ("AudioRecording.wav"));
MemoryBlock mb;
ScopedPointer<FileInputStream> fis = largeFile.createInputStream();
fis->readIntoMemoryBlock( mb );
auto s = Base64::toBase64( mb.getData(), mb.getSize() );
    or
auto s = mb.toBase64Encoding(); //read documentation

#3

Yep, that’s exactly what I was looking for. Thanks!


#4

Yeah, if you ever see (const void*, size_t size) as the parameter, you gotta convert whatever data you’re dealing with into a MemoryBlock first and then mb.getData(), mb.getSize() as the args. And use those stream methods that write to and read from a MemoryBlock


#5

Yea the thought with trying to use the InputStream from the file was to conserve on memory. With the memory block, I’m copying the file contents into a memory buffer, then when I convert it to Base64 and put it into a String, then i’m pretty much making another copy of that and storing that in memory also. Finally, I stuff it into a URL object (where it possibly gets copied again?), so a 50mb file might take up to 150mb of memory?

Maybe I should call mb.reset() right after I convert it to a Base64 string.


#6

If you use the scope pointer and create them on the stack you don’t have to worry about any of that because when the function exits, it’ll deconstruct them automatically