base64

在Java 8中,内置了Base64编解码相关的特性。我们可以在Java 8中使用下面三种类型的Base64编解码:

  • 简易模式:输出是完全按照A-Za-z0-9+/字符集映射的。编码不会自己增加输出行,解码器也不会接受任何超出A-Za-z0-9+/范围的内容。

  • URL模式:输出基于A-Za-z0-9+/的映射,但对于URL和文件名是安全的。

  • MIME模式:输出对于MIME类型的内容是友好的。如果超过76个字符,则会换行输出。,并且换行符\n之后会自动添加一个\r。如果某行没有\r则说明输出的内容已经结束。

base64的内部类和方法

Base64相关的内部类有:

  • Base64.Encoder:这是一个静态类。实现了Base64的编码功能,格式遵循了RFC 4648和RFC 2045标准。

  • Base64.Decoder:也是一个静态类。实现了Base64的解码功能。

相关的方法有:

  • getEncoder():该方法返回一个使用基本Base64编码格式的Encoder对象。相反的解码方法是getDecoder()。

  • getUrlEncoder():该方法返回一个使用URL类型的Base64编码格式的Encoder对象。相反的解码方法是getUrlDecoder()。

  • getMimeEncoder():该方法返回一个使用MIME类型的Base64编码格式的Encoder对象。相反的解码方法是getMimeDecoder()。

简单编码解码例子:

  1. // 使用基本的Base64编码
  2. String encodeToString = Base64.getEncoder().encodeToString("hello world".getBytes(Charsets.UTF_8));
  3. System.out.println(encodeToString); // aGVsbG8gd29ybGQ=
  4. byte[] decode = Base64.getDecoder().decode(encodeToString);
  5. System.out.println(new String(decode, Charsets.UTF_8)); // hello world
  6. // 使用URL类型的Base64编码
  7. encodeToString = Base64.getUrlEncoder().encodeToString("www.baidu.com/search".getBytes(Charsets.UTF_8));
  8. System.out.println(encodeToString); // d3d3LmJhaWR1LmNvbS9zZWFyY2g=
  9. decode = Base64.getUrlDecoder().decode(encodeToString);
  10. System.out.println(new String(decode, Charsets.UTF_8)); // www.baidu.com/search
  11. // MIME类型的Base64编码
  12. StringBuilder stringBuilder = new StringBuilder();
  13. for (int i = 0; i < 10; ++i) {
  14. stringBuilder.append(UUID.randomUUID().toString());
  15. }
  16. byte[] mimeBytes = stringBuilder.toString().getBytes(Charsets.UTF_8);
  17. encodeToString = Base64.getMimeEncoder().encodeToString(mimeBytes);
  18. /* 输出结果如下:
  19. YmM4MTkwMTYtY2IzMy00Y2RjLThiMzgtY2ZlNGQ4MzUyNTQ4ZmExODAwZTktMjgxOS00YzdlLWEy
  20. N2MtNjQ2YjVhNTY2ZDBiMTE0NzFiYTAtMjYzNC00ZDBjLWE3YTYtMzA0Y2JjZWU0NWUwNmZkMmQz
  21. MDctNGMwMS00NWJkLTk3ZjUtMzM2NjFkZjc0ZTNlYzZkNzJiYmEtMzE1Ny00YjhkLTlmN2ItYjE3
  22. OGY1M2I1NDM4Yjc0ZjA1YzgtM2I4NC00YWZmLTg1ZjAtZDRkODM0MDQ4NTg3ODVhNGZiNDUtZTE0
  23. Mi00NTBmLTk2MjMtN2E4ZmMwYjlmNzY1MjE2NGY0MzQtYzg4OS00YjBhLWFlNzItYjZkZmVjOTg1
  24. NzYzMzJiOTk1NTMtYmZkMy00MzNhLTgxMTktYjY1OTk1ODdhMzAyZDA2MWVhN2EtZDQ4ZC00NjU5
  25. LTgwMDYtNDllYjNkOGU5ZmZm
  26. */
  27. System.out.println(encodeToString);
  28. decode = Base64.getMimeDecoder().decode(encodeToString);
  29. // 输出结果:baac6ccc-e52d-4373-b5ee-e214fe707caab91efbea-877a-45d1-8d6b-9601d958280e0d4c269a-7fda-4d10-91a1-436e8b73b2d38c34bc80-a793-4e9a-a9a6-9e392e894776b4b6a403-310a-4784-886b-56f50807222e30c72ecd-2bff-4625-b153-edc381bc786c21e47091-abf8-4bc2-87f5-01a44ea4616aa72b9eb4-b582-4f46-b9a4-9066308462d9f9d6c4b8-8171-449c-bd61-9e4e4c153afa266be7cb-5112-46d5-8e84-b77aa2374a05
  30. System.out.println(new String(decode, Charsets.UTF_8));

流相关

java.util.Base64类封装了所有的BASE64编码器和解码器,还支持流的封装——这是一个非常优雅的构造——包括编码和效率都很高(无需缓冲Buffer)——即编码器和解码器的输入和输出无需缓冲Buffer。下面我们以一个例子来说明编码器是怎样封装FileOutputStream,以及解码器是怎样封装FileInputStream的,两者皆不需要缓冲Buffer:

String src = "This is the content of any resource read from somewhere" +
                " into a stream. This can be text, image, video or any other stream.";

// 编码器封装OutputStream, 文件F:/c.txt的内容是BASE64编码的形式写入的
try (OutputStream os = Base64.getEncoder().wrap(new FileOutputStream("F:/c.txt"))) {
    os.write(src.getBytes(Charsets.UTF_8));
}

// 解码器封装InputStream, 以及以流的方式解码, 无需缓冲
try (InputStream is = Base64.getDecoder().wrap(new FileInputStream("F:/c.txt"))) {
    int len;
    byte[] bytes = new byte[100];
    while ((len = is.read(bytes)) != -1) {
        System.out.print(new String(bytes, 0, len, Charsets.UTF_8));
    }
}