Рубрики
Без рубрики

Java Конвертировать PDF в Base64

Узнайте, как сделать base64 кодирования и расшифровки файла PDF с помощью Java 8 и Apache Commons Codec.

Автор оригинала: Sampada Wagde.

1. Обзор

В этом коротком учебнике мы увидим как сделать Base64 кодирования и расшифровки файла PDF с помощью Java 8 и Apache Commons Codec .

Но сначала, давайте быстро взглянуть на основы Base64.

2. Основы базы64

При отправке данных по проводу, мы должны отправить его в двоичном формате. Но если мы отправим только 0 и 1, различные протоколы транспортного слоя могут интерпретировать их по-разному, и наши данные могут быть повреждены в полете.

Итак, иметь переносимость и общие стандарты при передаче бинарных данных, Base64 вошел в .

Поскольку отправитель и получатель понимают и договариваются об использовании стандарта, вероятность того, что наши данные будут потеряны или неправильно истолкованы, значительно снижается.

Теперь давайте посмотрим несколько способов применить это к PDF.

3. Преобразование с использованием Java 8

Начиная с Java 8, у нас есть утилита java.util.Base64 который предоставляет кодеры и декодеры для схемы кодирования Base64. Он поддерживает основные, URL безопасные и MIME типов, как указано в RFC 4648 и RFC 2045 .

3.1. Кодирование

Чтобы преобразовать PDF в Base64, мы сначала должны получить его в байты и передать его через java.util.Base64.Encoder ‘ы кодировать метод :

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

Вот, IN_FILE это путь к нашему входу PDF.

3.2. Кодирование потоковой передачи

Для больших файлов или систем с ограниченной памятью гораздо эффективнее выполнять кодирование с помощью потока вместо того, чтобы читать все данные в памяти . Давайте посмотрим, как это сделать:

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 данных за один раз и передачи этих данных через кодер в ВыходСтрим .

3.3. Декодирование

На приемном конце мы получаем закодированный файл.

Так что теперь мы должны расшифровать его, чтобы вернуть наши оригинальные байты и написать их на FileOutputStream для декодированного PDF- :

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, мы должны добавить зависимость к нашей пом.xml :


    commons-codec
    commons-codec
    1.14

Последнюю версию вышеуказанного можно найти на Мавен Центральный .

4.2. Кодирование

Шаги такие же, как для Java 8, за исключением того, что на этот раз, мы переходят на наши оригинальные байты кодироватьBase64 метод 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. Потоковое кодирование

Кодирование потоковой передачи не поддерживается этой библиотекой.

4.4. Декодирование

Опять же, мы просто называем расшифроватьBase64 метод и написать результат в файл:

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:

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 методы, подтвердили, что:

  • закодированные и расшифрованые массивы byte разной длины
  • inFileBytes и расшифрованые массивы byte имеют одинаковую длину и имеют одинаковое содержимое

Конечно, мы также можем открыть расшифрованные PDF-файл, который мы создали, и увидеть, что содержимое такое же, как файл, который мы дали в качестве ввода.

6. Заключение

В этом быстром учебнике мы узнали больше о утилите Java Base64.

Мы также видели образцы кода для преобразование PDF в и из Base64 с использованием Java 8 и Apache Commons Codec . Интересно, что реализация JDK намного быстрее, чем у Apache.

Как всегда, исходный код доступен более на GitHub .