Base64 Stream Examples in Java

Published
Updated

The following examples use Apache’s Commons Codec library which is available on Maven Central by using the following dependency in your pom.xml file.

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

Reading and Writing a Base64 String Example

The following code will allow you to read or decode a Base64 encoded String in Java. This is useful for data that is short or limited in length. Note that there are two steps involved in this process:

  • First, we decode the data back into a binary format using the Base64 class’s decodeBase64 helper method. If your data was only binary data to begin with, you can simply use the data as it returns.
  • Second, since my original data was UTF-8 encoded text I convert that binary data back into a String using Apache’s StringUtils class.
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

public class Base64Example {
    
public static void main(String[] args) {
    // An example of a Base64 encoded String
    String base64 = "SGVsbG8gV29ybGQhIFRoaXMgaXMgYW4gZXhhbXBsZSBvZiBCYXNlNjQgZW5jb2RlZCBkYXRhLg==";

    // Decode the Base64 String and get a byte array containing the data
    byte[] bytes = Base64.decodeBase64(base64);

    // Convert the byte array to a UTF-8 String
    String utf8 = StringUtils.newStringUtf8(bytes);

    System.out.println(utf8);
}
}

Reading Base64 Data from a File Stream Example

The following code uses Apache’s Base64InputStream to read base64 data and decode it in a conventional stream type of format.

This is useful for decoding large amounts of Base64 encoded data or used within processes where data is consumed using a stream. You can simply wrap a FileInputStream with the Base64InputStream so base64 data is automatically decoded as you consume bytes from an InputStream.

// An example of a Base64 encoded String
String base64 = "SGVsbG8gV29ybGQhIFRoaXMgaXMgYW4gZXhhbXBsZSBvZiBCYXNlNjQgZW5jb2RlZCBkYXRhLg==";

// Write our Base64 String into a text file
try (FileWriter fileWriter = new FileWriter("base64.txt")) {
    fileWriter.write(base64);
}

// Use Apache's Base64InputStream to read the data in from our file
try (Scanner scanner = new Scanner(new Base64InputStream(new FileInputStream("base64.txt")))) {
    while (scanner.hasNextLine()) {
        // Print the line to the console
        System.out.println(scanner.nextLine());
    }
}

Reading Base64 data from a Socket InputStream

The following code can be used in tandem with the next section’s code on using a ServerSocket to write data. Simply run this codebase after starting the following server socket code.

We can even wrap a Java Socket’s InputStream with a Base64InputStream so that all of the data is sent over the network encoded in base64 format.

  • This is sometimes helpful when writing binary data to a socket that also sends zero or null byte terminated-strings. This way the low bytes of the binary data do not interfere with the newline or zero byte characters of the stream.

  • Additionally, this can be useful when attempting to send encrypted data over a socket in the same fashion, as what was originally a String is changed to bytes ranging from 0-255.

import org.apache.commons.codec.binary.Base64InputStream;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;

public class SocketReadBase64 {

public static void main(String[] args) throws IOException {

    Socket socket = new Socket();
    // Connect to our server (localhost, port 5555)
    socket.connect(new InetSocketAddress("0.0.0.0", 5555));

    // Wrap our Socket's InputStream with a Base64 InputStream
    try (Scanner scanner = new Scanner(new Base64InputStream(socket.getInputStream()))) {
        while (scanner.hasNextLine()) {
            // Print the line to the console
            System.out.println(scanner.nextLine());
        }
    }
}
}

Writing Base64 data using a ServerSocket OutputStream

The following code reads a Base64 Encoded file on the disk (decoding it in the process) and then re-encodes the file into base64, writing those bytes to the first socket connection the ServerSocket receives.

import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.codec.binary.Base64OutputStream;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketBase64 {

public static void main(String[] args) throws IOException {
    ServerSocket server = new ServerSocket(5555);

    Socket socket = server.accept();
    // Wrap the socket channel's OutputStream with a Base64OutputStream so data can be written back out in Base64
    try (Base64OutputStream base64OutputStream = new Base64OutputStream(socket.getOutputStream())) {
        // Read and decode our base64 data file with a Base64InputStream wrapping a FileInputStream
        try (Base64InputStream base64InputStream = new Base64InputStream(new FileInputStream("base64.txt"))) {
            // Write a single byte at a time to our outputstream. This can be further improved by using a buffer
            for (int data = base64InputStream.read(); data != -1; data = base64InputStream.read()) {
                base64OutputStream.write(data);
            }
        }
    }
}
}

Encode a file into base64 in Java

For comparison, here is how to encode a file into base64 without using streams. Note this will not scale well as it can consume large amounts of memory if you are converting a large file.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Base64;

public class Base64Example {

    public static void main(String[] args) throws IOException {

        // Read the file into a byte array using try with resources
        File file = new File("path/to/file.txt");
        byte[] data = new byte[(int) file.length()];
        try (FileInputStream fis = new FileInputStream(file)) {
            fis.read(data);
        }

        // Encode the byte array into base64
        String encoded = Base64.getEncoder().encodeToString(data);

        // Write the encoded base64 string to a file
        File outputFile = new File("path/to/output.txt");
        try (FileWriter fw = new FileWriter(outputFile)) {
            fw.write(encoded);
        }
    }
}