Чтение файла PNG и сохранение правильного формата в Java - PullRequest
4 голосов
/ 02 февраля 2020

Я пытаюсь прочитать файл PNG и затем отправить данные в ответ на запрос HTTP.

Когда я переименую исходный файл PNG в .txt и открою его в редакторе Я вижу, что содержимое выглядит примерно так:

8950 4e47 0d0a 1a0a 0000 000d 4948 4452
0000 074c 0000 0632 0806 0000 00bc 541d
2300 0000 0467 414d 4100 00b1 8e7c fb51
9300 0000 2063 4852 4d00 0087 0f00 008c
0f00 00fd 5200 0081 4000 007d 7900 00e9

Однако, когда я пытаюсь вручную прочитать его и сохранить в виде строки в Java, я получаю такой результат:

�PNG

���
IHDR��L��2����T#���gAMA����|�Q���� cHRM���������R���@��}y�����<����s<�w��
/iCCPICC Profile��HÇ�wTT��Ͻwz��0�z�.0��. Qf���Ml��@DE�����H��b!(�`HPb0�ï

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

Поскольку вывод содержит пару читаемых вещей, таких как "PNG", я полагаю, что меняю кодировку, когда прочитай это. Но я понятия не имею, как заставить его сохранить «правильный» формат / кодировку. Вот два разных подхода, которые я попробовал, и оба приводят к схожим ошибкам.

        InputStream inputStream = NewWebserverLauncher.class.getClassLoader().getResourceAsStream(url);
        if (inputStream == null) {
            // todo: error
            return "NO INPUT STREAM. Looked for \"" + url + "\"";
        }
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
        return result.toString();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();

Буду признателен за указатели на то, как правильно читать PNG!

1 Ответ

5 голосов
/ 02 февраля 2020

Однако, когда я пытаюсь прочитать его вручную и сохранить как строку в Java

Вы не должны этого делать. Это просто не текст.

Буду признателен за указатели на то, как я могу правильно читать PNG!

Не пытайтесь хранить двоичные данные как если это текст данные.

Ваш код, который копирует данные в ByteArrayOutputStream, в целом верен - до последней строки, когда вы преобразуете ее в строку. Просто не делай этого. Вместо этого позвоните toByteArray().

Текст, который вы указали в начале вашего поста, представляет собой hex представление байтов. Вы не сказали, что открыли, но я подозреваю, что это какая-то программа, которая либо предназначена для редактирования двоичных файлов, либо что-то, что распознает, что вы открываете файл, который на самом деле не является текстовым, несмотря на расширение файла.

Вы написали комментарий о том, что используемая вами библиотека позволяет отправлять только строку в качестве ответа. Если это действительно так, используйте другую библиотеку. Любая библиотека, которая на самом деле предполагает, что каждый HTTP-ответ является текстовым, в корне сломана, и вы можете обнаружить, что с ним много других проблем. Сначала я бы внимательно посмотрел - вы вполне можете найти способов отправки двоичных данных, и вы просто еще не нашли их. Возможно, вы захотите опубликовать новый вопрос, посвященный теме «Как я могу отправить двоичный ответ, используя библиотеку X?» а не о том, как обрабатывать двоичные данные как строку.

...