【问题标题】:Reading a PNG file and retaining the correct format in Java读取 PNG 文件并在 Java 中保留正确的格式
【发布时间】:2020-02-02 16:27:25
【问题描述】:

我正在尝试读取 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 的指针!

【问题讨论】:

  • 不要将字节串成字符串,只需“按原样”保存即可。
  • 不幸的是,我使用的库在设置响应正文时只接受String。基本上我阅读了InputStream,然后必须调用context.result(String) 来设置响应正文。我确信它可以解决,但在这一点上,我主要是好奇我是否可以将数据正确存储为字符串
  • 它是公共图书馆吗?如果有,是哪个?我认为您无法将图像作为字符串传递(没有一些严重的黑客攻击)
  • 我的错误,我只是仔细查看了一下,发现库 (Javalin) 确实有办法将 InputStream 设置为响应,而不仅仅是 String。我将调整我的代码,以便在必要时可以使用InputStream。感谢您的指导!

标签: java inputstream


【解决方案1】:

但是,当我尝试手动读取它并将其存储为 Java 中的字符串时

你不应该那样做。这不是文本。

不胜感激有关如何正确读取 PNG 的指针!

不要尝试将 二进制 数据存储为 文本 数据。

您将数据复制到ByteArrayOutputStream 的代码大体上是正确的 - 直到最后一行,当您将其转换为字符串时。只是不要那样做。请致电toByteArray()

您在帖子开头显示的文本是字节的hex 表示。你没有说你用什么打开它,但我怀疑它是一些专门用于编辑二进制文件的程序,或者识别你正在打开一个实际上不是文本的文件,尽管文件扩展名。

您写了一条评论,指出您使用的库只允许您发送一个字符串作为响应。如果确实如此,请使用不同的库。任何真正假定每个 HTTP 响应都是文本的库从根本上被破坏了,您可能会发现它还有许多其他问题。不过,我会先仔细查看 - 您可能会发现 种发送二进制数据的方式,而您只是还没有找到它们。您可能想发布一个专门关于“如何使用库 X 发送二进制响应?”的新问题。而不是关于如何将二进制数据视为字符串。

【讨论】:

  • 感谢您的信息!我仔细查看了文档,发现回复也可以是InputStream,我的错!我使用一种方法来处理文本和二进制数据,对于文本数据,我需要在发送响应之前编辑数据,这就是我使用字符串版本的原因。我将进行必要的更改,以便在必要时可以使用InputStream
猜你喜欢
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
相关资源
最近更新 更多