Java Konversi PDF ke Base64

1. Ikhtisar

Dalam tutorial singkat ini, kita akan melihat bagaimana melakukan pengkodean dan pengodean Base64 file PDF menggunakan Java 8 dan Apache Commons Codec .

Tapi pertama-tama, mari kita intip dasar-dasar Base64.

2. Dasar-dasar Base64

Saat mengirim data melalui kabel, kita perlu mengirimkannya dalam format biner. Tetapi jika kami hanya mengirim 0 dan 1, protokol lapisan transport yang berbeda dapat menafsirkannya secara berbeda dan data kami mungkin rusak dalam penerbangan.

Jadi, untuk memiliki portabilitas dan standar umum saat mentransfer data biner, Base64 hadir .

Karena pengirim dan penerima sama-sama memahami dan telah menyetujui penggunaan standar, kemungkinan data kami hilang atau disalahartikan sangat berkurang.

Sekarang mari kita lihat beberapa cara untuk menerapkan ini ke PDF.

3. Konversi Menggunakan Java 8

Dimulai dengan Java 8, kami memiliki utilitas java.util.Base64 yang menyediakan encoder dan decoder untuk skema encoding Base64. Ini mendukung jenis Basic, URL safe, dan MIME seperti yang ditentukan dalam RFC 4648 dan RFC 2045.

3.1. Pengkodean

Untuk mengkonversi PDF ke Base64, kita harus terlebih dahulu mendapatkannya dalam byte dan menyebarkannya melalui java.util.Base64.Encoder 's encode metode :

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

Di sini, IN_FILE adalah jalur ke PDF masukan kita.

3.2. Pengkodean Streaming

Untuk file yang lebih besar atau sistem dengan memori terbatas, jauh lebih efisien untuk melakukan pengkodean menggunakan aliran daripada membaca semua data dalam memori . Mari kita lihat bagaimana melakukannya:

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

Di sini, IN_FILE adalah jalur ke PDF input kami, dan OUT_FILE adalah jalur ke file yang berisi dokumen yang dikodekan Base64. Alih-alih membaca seluruh PDF ke dalam memori dan kemudian menyandikan dokumen lengkap di memori, kami membaca hingga 1Kb data pada satu waktu dan meneruskan data itu melalui encoder ke OutputStream .

3.3. Decoding

Di sisi penerima, kami mendapatkan file yang disandikan.

Jadi kita sekarang perlu mendekodekannya untuk mendapatkan kembali byte asli kita dan menuliskannya ke FileOutputStream untuk mendapatkan PDF yang diterjemahkan :

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

Di sini, OUT_FILE adalah jalur menuju PDF kita yang akan dibuat.

4. Konversi Menggunakan Apache Commons

Selanjutnya, kami akan menggunakan paket Apache Commons Codec untuk mencapai hal yang sama. Ini didasarkan pada RFC 2045 dan mendahului implementasi Java 8 yang kita diskusikan sebelumnya. Jadi, saat kami perlu mendukung beberapa versi JDK (termasuk yang lama) atau vendor, ini berguna sebagai API pihak ketiga.

4.1. Maven

Untuk dapat menggunakan pustaka Apache, kita perlu menambahkan ketergantungan ke pom.xml kita :

 commons-codec commons-codec 1.14  

Versi terbaru di atas dapat ditemukan di Maven Central.

4.2. Pengkodean

Langkah-langkahnya sama seperti untuk Java 8, kecuali kali ini, kami meneruskan byte asli kami ke metode encodeBase64 dari kelas org.apache.commons.codec.binary.Base64 :

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

4.3. Pengkodean Streaming

Pengkodean streaming tidak didukung oleh pustaka ini.

4.4. Decoding

Sekali lagi, kita cukup memanggil metode decodeBase64 dan menulis hasilnya ke file:

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

5. Pengujian

Sekarang kami akan menguji encoding dan decoding kami menggunakan tes JUnit sederhana:

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(); } }

Seperti yang kita lihat, kita pertama kali membaca byte masukan dalam @BeforeClass metode, dan di kedua kami @ Test metode, memverifikasi bahwa:

  • array byte yang dikodekan dan didekodekan memiliki panjang yang berbeda
  • inFileBytes dan array byte yang didekodekan memiliki panjang yang sama dan memiliki konten yang sama

Tentu saja, kami juga dapat membuka file PDF yang telah didekodekan yang kami buat dan melihat bahwa isinya sama dengan file yang kami berikan sebagai input.

6. Kesimpulan

Dalam tutorial singkat ini, kita belajar lebih banyak tentang utilitas Base64 Java.

Kami juga melihat contoh kode untuk mengonversi PDF menjadi dan dari Base64 menggunakan Java 8 dan Apache Commons Codec . Menariknya, implementasi JDK jauh lebih cepat daripada Apache.

Seperti biasa, kode sumber tersedia di GitHub.