【问题标题】:What's the most efficient way to add data mid way through a stream of bytes?通过字节流中途添加数据的最有效方法是什么?
【发布时间】:2011-11-21 22:31:20
【问题描述】:

我一直在制作一个图像缩放器,它使用 Java 中的 ImageIO 库将它们转换为缓冲图像。不幸的是,它不能识别我可能传递给它的每种类型的 JPEG,因此我需要“转换”这些其他类型。我转换它们的方式是从标准 JFIF JPEG 中获取现有的 APP0 标签,我想做的是在文件的第 3 个字节插入 18 个字节的数据(FFE0 标记和 16 个字节的 APP0 标签)和然后我想将文件的其余部分添加到该文件的末尾。

所以概括地说,在流/文件中途添加/插入数据字节的最有效方法是什么?

提前致谢, 阿列克谢蓝。

这个问题与我之前的一个问题有关,因此我要感谢 onemasse 在那里给出的答案。 Java JPEG Converter for Odd Image Types

【问题讨论】:

    标签: java stream


    【解决方案1】:

    如果您从流中读取图像,您可以创建一个代理,该代理的作用类似于输入流并接受输出流。覆盖 read 方法,以便在丢失时返回额外丢失的字节。

    可以通过扩展FilterInputStream http://download.oracle.com/javase/6/docs/api/java/io/FilterInputStream.html来做代理

    【讨论】:

      【解决方案2】:

      如果是文件,推荐的方法是将现有文件复制到新文件,在适当的位置插入、更改或删除字节。然后将新文件重命名为旧文件。

      理论上,您可以尝试使用 RandomAccessFile(或等效文件)对现有文件执行就地更新。然而,它有点棘手,没有你想象的那么高效,而且……最重要的是……它不安全。 (如果您的应用程序或系统在不合时宜的时刻死机,您将得到一个损坏的文件,并且无法恢复它。)

      【讨论】:

        【解决方案3】:

        PushbackInputStream 可能是您需要的。

        【讨论】:

          【解决方案4】:

          感谢大佬们的建议,一开始我用的是FilterInputStream,后来发现不用了,我用下面这段代码输入了我的APP0 Hex标签:

          private static final String APP0Marker = "FF E0 00 10 4A 46 49 46 00 01 01 01 00 8B 00 8B 00 00";
          

          并在所需的转换器方法中:

                  if (isJPEG(path))
                  {
                      fis = new FileInputStream(path);
                      bytes = new byte[(int)(new File(path).length())];
                      APP0 = hexStringToByteArray(APP0Marker.replaceAll(" ", ""));
          
                      for (int index = 0; index < bytes.length; index++)
                      {
                          if (index >= 2 && index <= (2 + APP0.length - 1))
                          {
                              b = APP0[index-2];
                          }
                          else
                          {
                              b = (byte) fis.read();
                          }//if-else
          
                          bytes[index] = b;
                      }//for
          
                      //Write new image file
                      out = new FileOutputStream(path);
                      out.write(bytes);
                      out.flush();
                  }//if
          

          希望这可以帮助遇到类似问题的人:)

          【讨论】:

            猜你喜欢
            • 2014-01-12
            • 2017-09-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-05-13
            • 1970-01-01
            • 2020-07-20
            • 1970-01-01
            相关资源
            最近更新 更多