Search code examples
javafilebase64decodeencode

encode/decode file in java with Base64


I've written a encode/decode file in Java like below

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class Test {
    
    public static void encodeFile(String inputfile, String outputfile) throws IOException {
        byte[] input_file = Files.readAllBytes(Paths.get(inputfile));
        byte[] encodedBytes = Base64.getEncoder().encode(input_file);
        String encodedString =  new String(encodedBytes);
        
        File ff =  new File(outputfile);
        FileOutputStream fileOut = new FileOutputStream(ff);
        OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
        outStream.write(encodedString);
        outStream.flush();
    }
    
    public static void decodeFile(String encodedfilecontent, String decodedfile) throws IOException {   
        byte[] decoded = Base64.getDecoder().decode(encodedfilecontent);
        String decodedString =  new String(decoded);
        
        File ff =  new File(decodedfile);
        FileOutputStream fileOut = new FileOutputStream(ff);
        OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
        outStream.write(decodedString);
        outStream.flush();
    }

    public static void main(String[] args) throws IOException {
        
        String inputfile = "C:\\Users\\John\\Desktop\\Files.zip";
        
        String outputfile = "C:\\Users\\John\\Desktop\\encoded.txt";
        
        encodeFile(inputfile, outputfile);
        
        String encodedfilecontent = new String(Files.readAllBytes(Paths.get(outputfile)));
        
        String decodedfile = "C:\\Users\\John\\Desktop\\DecodedFiles.zip";
        
        decodeFile(encodedfilecontent, decodedfile);

    }

}

The above code has 2 methods:
1- To encode file to Base64 and write it in a text file
2- To decode the text file and write it back into a new file
All the input/output files are in desktop
I've test this and this encode and decode methods only work if inputfile is simple text file. If the input file is an image or a zip file like this example, the decoded file will be broken. Can you explain why it is broken like this?

Is there anyway to universally encode any type of file to Base64 and decode it back? If yes can you tweak the above code to do that?


Solution

  • You are not closing the files. Also there is the mentioned problem when you use text (String/Reader/Writer) for binary data: corrupt data, slower, double memory, platform dependent when not specifying the encoding.

    The optimal solution is not to take the bytes in memory, additionally making a 8/5 larger byte array with base 64.

    Use try-with-resources to automatically close the files, even on an exception (like illegal Base 64 chars).

    public static void encodeFile(String inputFile, String outputFile)
            throws IOException {
        Path inPath = Paths.get(inputFile);
        Path outPath = Paths.get(outputFile);
        try (OutputStream out = Base64.getEncoder().wrap(Files.newOutputStream(outPath))) {
            Files.copy(inPath, out);
        }
    }
    
    public static void decodeFile(String encodedfilecontent, String decodedfile)
            throws IOException {
        Path inPath = Paths.get(encodedfilecontent);
        Path outPath = Paths.get(decodedfile);
        try (InputStream in = Base64.getDecoder().wrap(Files.newInputStream(inPath))) {
            Files.copy(in, outPath);
        }
    }