Java PDF in Base64 konvertieren

1. Übersicht

In diesem kurzen Tutorial erfahren Sie, wie Sie eine PDF-Datei mit Base64 mit Java 8 und Apache Commons Codec codieren und decodieren .

Aber zuerst werfen wir einen kurzen Blick auf die Grundlagen von Base64.

2. Grundlagen von Base64

Wenn wir Daten über das Kabel senden, müssen wir sie im Binärformat senden. Wenn wir jedoch nur Nullen und Einsen senden, können verschiedene Transportschichtprotokolle diese unterschiedlich interpretieren und unsere Daten können im Flug beschädigt werden.

Um Portabilität und gemeinsame Standards bei der Übertragung von Binärdaten zu gewährleisten, kam Base64 ins Spiel .

Da sowohl der Absender als auch der Empfänger den Standard verstehen und sich darauf geeinigt haben, wird die Wahrscheinlichkeit, dass unsere Daten verloren gehen oder falsch interpretiert werden, erheblich verringert.

Lassen Sie uns nun einige Möglichkeiten sehen, wie Sie dies auf ein PDF anwenden können.

3. Konvertierung mit Java 8

Ab Java 8 haben wir ein Dienstprogramm java.util.Base64 , das Codierer und Decodierer für das Base64-Codierungsschema bereitstellt. Es unterstützt Basic-, URL-sichere und MIME-Typen, wie in RFC 4648 und RFC 2045 angegeben.

3.1. Codierung

Um eine PDF - Datei in Base64 zu konvertieren, müssen wir zuerst es in Bytes zu erhalten und führen es durch java.util.Base64.Encoder ‚s kodieren Methode :

byte[] inFileBytes = Files.readAllBytes(Paths.get(IN_FILE)); byte[] encoded = java.util.Base64.getEncoder().encode(inFileBytes);

Hier ist IN_FILE der Pfad zu unserer Eingabe-PDF.

3.2. Streaming-Codierung

Bei größeren Dateien oder Systemen mit begrenztem Speicher ist es viel effizienter, die Codierung mithilfe eines Streams durchzuführen, anstatt alle Daten im Speicher zu lesen . Schauen wir uns an, wie dies erreicht werden kann:

try (OutputStream os = java.util.Base64.getEncoder().wrap(new FileOutputStream(OUT_FILE)); FileInputStream fis = new FileInputStream(IN_FILE)) { byte[] bytes = new byte[1024]; int read; while ((read = fis.read(bytes)) > -1) { os.write(bytes, 0, read); } }

Hier ist IN_FILE der Pfad zu unserer Eingabe-PDF und OUT_FILE der Pfad zu einer Datei, die das Base64-codierte Dokument enthält. Anstatt das gesamte PDF in den Speicher einzulesen und dann das gesamte Dokument im Speicher zu codieren, lesen wir bis zu 1 KB Daten gleichzeitig und leiten diese Daten über den Encoder in den OutputStream .

3.3. Dekodierung

Am empfangenden Ende erhalten wir die verschlüsselte Datei.

Jetzt müssen wir es dekodieren, um unsere ursprünglichen Bytes zurückzugewinnen und sie in einen FileOutputStream zu schreiben , um das dekodierte PDF zu erhalten :

byte[] decoded = java.util.Base64.getDecoder().decode(encoded); FileOutputStream fos = new FileOutputStream(OUT_FILE); fos.write(decoded); fos.flush(); fos.close();

Hier ist OUT_FILE der Pfad zu unserem PDF, das erstellt werden soll.

4. Konvertierung mit Apache Commons

Als Nächstes verwenden wir das Apache Commons Codec-Paket, um dasselbe zu erreichen. Es basiert auf RFC 2045 und ist älter als die zuvor diskutierte Java 8-Implementierung. Wenn wir also mehrere JDK-Versionen (einschließlich älterer Versionen) oder Anbieter unterstützen müssen, ist dies als API eines Drittanbieters nützlich.

4.1. Maven

Um die Apache-Bibliothek verwenden zu können, müssen wir unserer pom.xml eine Abhängigkeit hinzufügen :

 commons-codec commons-codec 1.14  

Die neueste Version der oben genannten Version finden Sie auf Maven Central.

4.2. Codierung

Die Schritte sind die gleichen wie für Java 8, außer dass wir diesmal unsere ursprünglichen Bytes an die encodeBase64- Methode der org.apache.commons.codec.binary.Base64- Klasse weitergeben:

byte[] inFileBytes = Files.readAllBytes(Paths.get(IN_FILE)); byte[] encoded = org.apache.commons.codec.binary.Base64.encodeBase64(inFileBytes); 

4.3. Streaming-Codierung

Die Streaming-Codierung wird von dieser Bibliothek nicht unterstützt.

4.4. Dekodierung

Wieder rufen wir einfach die decodeBase64- Methode auf und schreiben das Ergebnis in eine Datei:

byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(encoded); FileOutputStream fos = new FileOutputStream(OUT_FILE); fos.write(decoded); fos.flush(); fos.close(); 

5. Testen

Jetzt testen wir unsere Codierung und Decodierung mit einem einfachen JUnit-Test:

public class EncodeDecodeUnitTest { private static final String IN_FILE = // path to file to be encoded from; private static final String OUT_FILE = // path to file to be decoded into; private static byte[] inFileBytes; @BeforeClass public static void fileToByteArray() throws IOException { inFileBytes = Files.readAllBytes(Paths.get(IN_FILE)); } @Test public void givenJavaBase64_whenEncoded_thenDecodedOK() throws IOException { byte[] encoded = java.util.Base64.getEncoder().encode(inFileBytes); byte[] decoded = java.util.Base64.getDecoder().decode(encoded); writeToFile(OUT_FILE, decoded); assertNotEquals(encoded.length, decoded.length); assertEquals(inFileBytes.length, decoded.length); assertArrayEquals(decoded, inFileBytes); } @Test public void givenJavaBase64_whenEncodedStream_thenDecodedStreamOK() throws IOException { try (OutputStream os = java.util.Base64.getEncoder().wrap(new FileOutputStream(OUT_FILE)); FileInputStream fis = new FileInputStream(IN_FILE)) { byte[] bytes = new byte[1024]; int read; while ((read = fis.read(bytes)) > -1) { os.write(bytes, 0, read); } } byte[] encoded = java.util.Base64.getEncoder().encode(inFileBytes); byte[] encodedOnDisk = Files.readAllBytes(Paths.get(OUT_FILE)); assertArrayEquals(encoded, encodedOnDisk); byte[] decoded = java.util.Base64.getDecoder().decode(encoded); byte[] decodedOnDisk = java.util.Base64.getDecoder().decode(encodedOnDisk); assertArrayEquals(decoded, decodedOnDisk); } @Test public void givenApacheCommons_givenJavaBase64_whenEncoded_thenDecodedOK() throws IOException { byte[] encoded = org.apache.commons.codec.binary.Base64.encodeBase64(inFileBytes); byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(encoded); writeToFile(OUT_FILE, decoded); assertNotEquals(encoded.length, decoded.length); assertEquals(inFileBytes.length, decoded.length); assertArrayEquals(decoded, inFileBytes); } private void writeToFile(String fileName, byte[] bytes) throws IOException { FileOutputStream fos = new FileOutputStream(fileName); fos.write(bytes); fos.flush(); fos.close(); } }

Wie wir sehen können, haben wir zuerst die Eingabebytes in einer @ BeforeClass- Methode gelesen und in unseren beiden @ Test- Methoden Folgendes überprüft:

  • codierte und decodierte Byte-Arrays sind unterschiedlich lang
  • inFileBytes und decodierte Byte-Arrays sind gleich lang und haben den gleichen Inhalt

Natürlich können wir auch die von uns erstellte dekodierte PDF-Datei öffnen und feststellen, dass der Inhalt mit der Datei übereinstimmt, die wir als Eingabe angegeben haben.

6. Fazit

In diesem kurzen Tutorial haben wir mehr über das Base64-Dienstprogramm von Java erfahren.

Wir haben auch Codebeispiele zum Konvertieren einer PDF-Datei in und aus Base64 mit Java 8 und Apache Commons Codec gesehen . Interessanterweise ist die JDK-Implementierung viel schneller als die Apache-Implementierung.

Wie immer ist der Quellcode über GitHub verfügbar.