Java Convert PDF to Base64
1.概述
在这个简短的教程中,我们将看到如何使用Java 8和Apache Commons Codec对PDF文件进行Base64编码和解码。
但是首先,让我们快速了解一下Base64的基础知识。
2. Base64的基础
通过有线发送数据时,我们需要以二进制格式发送数据。但是,如果我们仅发送0和1,则不同的传输层协议可能会不同地解释它们,并且我们的数据可能会在飞行中损坏。
因此,为了在传输二进制数据时具有可移植性和通用标准,图片中使用了Base64。
由于发送者和接收者都理解并同意使用该标准,因此大大降低了我们的数据丢失或被误解的可能性。
现在,让我们看看将其应用于PDF的几种方法。
3.使用Java 8进行转换
从Java 8开始,我们有一个实用程序java.util.Base64,它为Base64编码方案提供编码器和解码器。它支持RFC 4648和RFC 2045中指定的基本,URL安全和MIME类型。
3.1。编码方式
要将PDF转换为Base64,我们首先需要以字节为单位获取它,并将其通过java.util.Base64.Encoder的encoding方法传递:
1 2 | byte[] inFileBytes = Files.readAllBytes(Paths.get(IN_FILE)); byte[] encoded = java.util.Base64.getEncoder().encode(inFileBytes); |
在这里,IN_FILE是输入PDF的路径。
3.2。流编码
对于较大的文件或内存有限的系统,使用流而不是读取内存中的所有数据来执行编码会更加有效。让我们看看如何完成此任务:
1 2 3 4 5 6 7 8 | 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); } } |
在这里,IN_FILE是输入PDF的路径,而OUT_FILE是包含Base64编码文档的文件的路径。而不是将整个PDF读取到内存中,然后在内存中对整个文档进行编码,我们一次读取多达1Kb的数据,并将该数据通过编码器传递到OutputStream。
3.3。解码
在接收端,我们得到了编码文件。
因此,我们现在需要对其进行解码以获取原始字节,并将其写入FileOutputStream以获得解码后的PDF:
1 2 3 4 5 6 | byte[] decoded = java.util.Base64.getDecoder().decode(encoded); FileOutputStream fos = new FileOutputStream(OUT_FILE); fos.write(decoded); fos.flush(); fos.close(); |
在这里,OUT_FILE是要创建的PDF的路径。
4.使用Apache Commons进行转换
接下来,我们将使用Apache Commons Codec软件包来实现相同目的。它基于RFC 2045,早于我们之前讨论的Java 8实现。因此,当我们需要支持多个JDK版本(包括旧版本)或供应商时,这可以作为第三方API派上用场。
4.1。马文
为了能够使用Apache库,我们需要在pom.xml中添加一个依赖项:
1 2 3 4 5 | <dependency> <groupId>commons-codec</groupId> commons-codec</artifactId> <version>1.14</version> </dependency> |
上面的最新版本可以在Maven Central中找到。
4.2。编码方式
步骤与Java 8相同,除了这次,我们将原始字节传递给org.apache.commons.codec.binary.Base64class的encodeBase64方法:
1 2 | byte[] inFileBytes = Files.readAllBytes(Paths.get(IN_FILE)); byte[] encoded = org.apache.commons.codec.binary.Base64.encodeBase64(inFileBytes); |
4.3。流编码
该库不支持流编码。
4.4。解码
同样,我们只需要调用encodeBase64方法并将结果写入文件即可:
1 2 3 4 5 6 | byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(encoded); FileOutputStream fos = new FileOutputStream(OUT_FILE); fos.write(decoded); fos.flush(); fos.close(); |
5.测试
现在,我们将使用简单的JUnit测试来测试编码和解码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 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(); } } |
如我们所见,我们首先在@BeforeClass方法中读取输入字节,然后在两个@Test方法中验证:
编码和解码的字节数组的长度不同
inFileBytes和解码的字节数组长度相同,内容相同
当然,我们也可以打开我们创建的解码的PDF文件,并查看其内容与我们输入的文件相同。
六,结论
在本快速教程中,我们了解了有关Java的Base64实用程序的更多信息。
我们还看到了使用Java 8和Apache Commons Codec将PDF转换为Base64和从Base64转换PDF的代码示例。有趣的是,JDK的实现比Apache的实现快得多。
与往常一样,源代码可以在GitHub上获得。