To convert a file to Base64 in Java, read the file into a byte array with java.nio.file.Files and pass it to java.util.Base64.getEncoder().encodeToString(bytes); since Java 8 the standard library ships java.util.Base64 with no third-party dependency, the encoder preserves every byte verbatim including zero bytes and arbitrary binary sequences, the output uses the canonical RFC 4648 alphabet of A–Z, a–z, 0–9, plus and slash, and the final group is always padded with one or two equals signs so the result is a multiple of four characters. Because the encoding represents three input bytes as four output characters, a file of 1024 bytes produces exactly 1368 Base64 characters including padding, which is the canonical padded size for that input length. The same class also exposes getDecoder(), getUrlEncoder() and getMimeEncoder() so the reverse direction and the URL-safe or line-wrapped variants are reachable from a single import. For quick verification without writing a test harness, a browser-based File to Base64 Converter produces identical canonical text from a local file of up to 10 MB without uploading bytes, which is useful when comparing Java output against a reference string.

convert file to base64 in java
Convert File to Base64 in Java with java.util.Base64

Java's Built-In Base64 Support Since Java 8

Since Java 8 the standard library includes java.util.Base64, which lives in the java.base module and therefore needs no extra dependency on the classpath. Three encoder factories are exposed through static methods: getEncoder() returns the canonical RFC 4648 encoder, getUrlEncoder() returns the URL and filename safe variant that replaces plus with minus and slash with underscore, and getMimeEncoder() returns an encoder that wraps every 76 characters with a line break and emits a final CRLF after the last line, matching the historical MIME specification. Three matching decoders round out the API.

The canonical encoder accepts a byte array and produces a single ASCII string that uses the standard alphabet plus one or two = characters as pad when the input length is not a multiple of three. Because the implementation operates on bytes rather than characters, it never interprets the payload: a JPEG, a PDF, an encrypted blob or an executable all travel through unchanged. There is no transcoding of line endings, no re-encoding of images, no normalization of UTF-8, no inspection of file headers and no rewriting of metadata. The class is reversible, so passing the encoded string to getDecoder().decode() returns the original byte array bit-for-bit.

How to Convert a File to Base64 in Java

The shortest practical path from a file on disk to a Base64 string uses java.nio.file.Files to load the bytes and java.util.Base64 to encode them. The following steps assume a Java 8 or later toolchain and a file path the JVM can read.

  1. Import the classes. Add import java.nio.file.Files;, import java.nio.file.Path;, import java.nio.file.Paths; and import java.util.Base64;, then wrap the body in a try-catch for java.io.IOException.
  2. Resolve the path. Build a Path with Path path = Paths.get("invoice.pdf");; replace the argument with an absolute path or one read from arguments, configuration or environment variables when needed.
  3. Read the bytes. Call byte[] data = Files.readAllBytes(path);; this loads the entire file into memory, which is acceptable for files up to a few hundred megabytes on a modern JVM and the standard choice for files well below the 10 MB threshold used by most browser-based converters.
  4. Encode with the canonical encoder. Call String b64 = Base64.getEncoder().encodeToString(data);; the result is an ASCII string in the standard alphabet, padded to a multiple of four characters with =.
  5. Use the string. Pass b64 to a JSON field, an HTTP header, a database column, a property file or a test fixture; treat it like any other ASCII string and remember it is roughly one third larger than the source.
  6. Confirm the size. Compute the expected character count as 4 * ceil(bytes.length / 3); if the actual length differs, the encoder is not RFC 4648 canonical and the receiving system may reject it.

For a 1024-byte file, the expected Base64 length is 4 * ceil(1024 / 3) = 4 * 342 = 1368 characters, including the two pad signs of the final group. Encoding grows the payload by roughly one third, so a 1 MB file becomes about 1.33 MB of text. Plan log lines, ticket fields and database columns accordingly.

Encoder and Decoder Variants in java.util.Base64

MethodAlphabetPaddingLine wrappingTypical use
getEncoder()A–Z a–z 0–9 + /Required =NoneCanonical RFC 4648 output, JSON fields, headers
getUrlEncoder()A–Z a–z 0–9 - _Required =NoneQuery strings, filenames, tokens in URLs
getMimeEncoder()A–Z a–z 0–9 + /Required =Every 76 chars + trailing CRLFEmail bodies, MIME attachments, legacy transports
getDecoder()Standard + / onlyStrictRejects whitespaceReverse of getEncoder()
getUrlDecoder()URL-safe - _ onlyStrictRejects whitespaceReverse of getUrlEncoder()
getMimeDecoder()Standard + / onlyStrictIgnores line breaksReverse of getMimeEncoder()

Pick the encoder that matches the receiver's expectation. A common mistake is sending MIME-wrapped output to a JSON parser that does not strip line breaks, or sending URL-safe output to a decoder that only knows plus and slash. When in doubt the canonical getEncoder() plus getDecoder() pair is the safest default.

Decoding Base64 Back to a File in Java

The reverse direction mirrors the encoding path. Read the encoded string, hand it to getDecoder().decode(), and write the resulting byte array to disk.

  1. Strip any container the input might be wrapped in: remove a data: URL prefix and the comma that follows it only when you know the prefix is well formed, and remove MIME line breaks only when the payload was produced by getMimeEncoder().
  2. Call byte[] bytes = Base64.getDecoder().decode(encoded);; the decoder requires the standard alphabet plus = padding and refuses whitespace, missing padding or non-zero pad bits.
  3. Build the destination path with Path out = Paths.get("decoded.bin");; pick a filename and extension that reflect the real format, not the Base64 prefix.
  4. Call Files.write(out, bytes); to persist the bytes; Files.write creates the file or overwrites an existing one.
  5. Validate the result with an appropriate application or a cryptographic hash such as SHA-256 when integrity matters, because the filename extension does not inspect the bytes.

Strict decoding matters because the same payload can be spelled in several valid-looking ways. The decoder in java.util.Base64 enforces canonical form by re-encoding the result and comparing; non-canonical inputs raise IllegalArgumentException rather than silently producing a different byte array.

Verifying Java Output with a Local Browser Tool

Before shipping Base64 between services it helps to confirm that the Java output is byte-identical to a reference string. A local-browser File to Base64 Converter accepts files up to 10 MB and produces the same canonical RFC 4648 padded text, all inside the current tab without uploading bytes, which is useful when comparing against expected values from a specification or a test fixture. For the reverse direction the same tool accepts canonical Base64 with no whitespace, takes a filename and MIME type from you, and creates a temporary Blob URL that you can download and inspect.

PreservesDoes not do
Exact byte content of the sourceTranscode images or rewrite media
Zero bytes and arbitrary binaryNormalize line endings
Original file format and headersInspect or infer the file format
Required RFC 4648 paddingAdd a data: URL prefix
Canonical zero pad bitsInsert 76-character line wrapping

Because the browser reads the file through the W3C File API as an ArrayBuffer and never sends the bytes to a server, you can use the same machine you trust with the Java code. Avoid shared or untrusted machines for files that contain credentials, personal data, signing keys or executable payloads: Base64 is encoding, not protection, and the resulting string can still carry everything the original file did. For a deeper look at canonical output and strict decoder behavior, the canonical RFC 4648 output walkthrough pairs well with this guide.

Pitfalls Around Padding and Pad Bits

Canonical RFC 4648 output ends with zero, one or two = characters so the encoded length is a multiple of four. When the last group holds one input byte it produces two characters and two pad signs; when it holds two input bytes it produces three characters and one pad sign. Decoders that omit padding or accept malformed padding can hide real differences in the input. A stricter problem is non-zero pad bits: the unused bits of the final character carry no information, so a canonical encoder always writes zeros there; if a sender writes non-zero values to smuggle data, the decoder must reject the input. RFC 4648 defines the alphabet, padding and the test vectors that lock correctness, including the empty, f, fo, foo, foob, fooba and foobar strings.

  • Mixing alphabets. URL-safe and standard alphabets are not interchangeable. A receiver expecting plus and slash will fail on minus and underscore.
  • Keeping line breaks. getEncoder() never inserts them, but many copy-paste sources wrap at 76 characters; the strict getDecoder() will reject those unless you switch to getMimeDecoder() or strip the breaks first.
  • Trusting the filename. Decoded bytes have no inherent extension; renaming decoded.bin to decoded.pdf does not make it a PDF. Open the file with the right application or compute a hash.
  • Confusing encoding with security. Base64 is reversible. It is not encryption, hashing, signing, compression, sanitization or malware scanning. Use a real primitive for each of those jobs.