Java Tukar PDF ke Base64

1. Gambaran keseluruhan

Dalam tutorial ringkas ini, kita akan melihat bagaimana melakukan pengekodan dan penyahkodan Base64 fail PDF menggunakan Java 8 dan Apache Commons Codec .

Tetapi pertama, mari kita lihat sekilas asas Base64.

2. Asas Base64

Semasa menghantar data melalui wayar, kita perlu menghantarnya dalam format binari. Tetapi jika kami hanya mengirim 0 dan 1, protokol lapisan pengangkutan yang berbeza dapat menafsirkannya secara berbeza dan data kami mungkin rosak semasa penerbangan.

Oleh itu, untuk mempunyai kemudahan dan standard yang sama semasa memindahkan data binari, Base64 muncul dalam gambar .

Oleh kerana pengirim dan penerima memahami dan telah bersetuju untuk menggunakan standard tersebut, kemungkinan data kita tersesat atau disalahtafsirkan sangat berkurang.

Sekarang mari kita lihat beberapa cara untuk menerapkannya pada PDF.

3. Penukaran Menggunakan Java 8

Bermula dengan Java 8, kami mempunyai utiliti java.util.Base64 yang menyediakan pengekod dan penyahkod untuk skema pengekodan Base64. Ini menyokong jenis Basic, URL safe dan MIME seperti yang ditentukan dalam RFC 4648 dan RFC 2045.

3.1. Pengekodan

Untuk menukar PDF ke dalam Base64, kita perlu pertama untuk mendapatkannya dalam bait dan lulus melalui java.util.Base64.Encoder 's mengekod kaedah :

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

Di sini, IN_FILE adalah jalan ke PDF input kami.

3.2. Pengekodan Streaming

Untuk fail atau sistem yang lebih besar dengan memori terhad, jauh lebih efisien untuk melakukan pengekodan menggunakan aliran daripada membaca semua data dalam memori . Mari lihat bagaimana mencapainya:

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 jalan ke input PDF kami, dan OUT_FILE adalah jalan ke fail yang mengandungi dokumen yang dikodkan Base64. Daripada membaca keseluruhan PDF ke dalam memori dan kemudian mengekodkan dokumen penuh dalam memori, kami membaca hingga 1Kb data sekaligus dan menyampaikan data tersebut melalui pengekod ke dalam OutputStream .

3.3. Penyahkodan

Pada akhir penerimaan, kami mendapat fail yang dikodkan.

Oleh itu, kita sekarang perlu menyahkodnya untuk mendapatkan semula bait asal dan menulisnya ke FileOutputStream untuk mendapatkan PDF yang disahkod :

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 jalan ke PDF kami untuk dibuat.

4. Penukaran Menggunakan Apache Commons

Seterusnya, kami akan menggunakan pakej Apache Commons Codec untuk mencapai yang sama. Ini berdasarkan RFC 2045 dan mendahului pelaksanaan Java 8 yang telah kita bincangkan sebelumnya. Oleh itu, apabila kita perlu menyokong pelbagai versi JDK (termasuk versi lama) atau vendor, ini berguna sebagai API pihak ketiga.

4.1. Maven

Untuk dapat menggunakan perpustakaan Apache, kita perlu menambahkan kebergantungan pada pom.xml kami :

 commons-codec commons-codec 1.14  

Versi terbaru di atas boleh didapati di Maven Central.

4.2. Pengekodan

Langkahnya sama seperti untuk Java 8, kecuali kali ini, kami meneruskan byte asal kami ke kaedah 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. Pengekodan Streaming

Pengekodan streaming tidak disokong oleh pustaka ini.

4.4. Penyahkodan

Sekali lagi, kita hanya memanggil kaedah decodeBase64 dan menulis hasilnya ke fail:

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

5. Menguji

Sekarang kita akan menguji pengekodan dan penyahkodan kita menggunakan ujian JUnit mudah:

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, pertama kali kita membaca input byte dalam kaedah @BeforeClass , dan dalam kedua kaedah @Test kami , mengesahkan bahawa:

  • tatasusunan bait yang dikodkan dan disahkod mempunyai panjang yang berbeza
  • inFileBytes dan dinyahkod tatasusunan bait mempunyai panjang yang sama dan mempunyai kandungan yang sama

Sudah tentu, kita juga dapat membuka fail PDF yang disahkod yang kita buat dan melihat bahawa isinya sama dengan fail yang kita berikan sebagai input.

6. Kesimpulannya

Dalam tutorial ringkas ini, kami mempelajari lebih lanjut mengenai utiliti Java Base64.

Kami juga melihat contoh kod untuk menukar PDF ke dan dari Base64 menggunakan Java 8 dan Apache Commons Codec . Menariknya, pelaksanaan JDK jauh lebih pantas daripada Apache.

Seperti biasa, kod sumber tersedia di GitHub.