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’sdecodeBase64
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);
}
}
}