通过字节流中途添加数据的最有效方法是什么?

时间:2011-11-08 12:20:55

标签: java stream

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

总而言之,在流/文件中途添加/插入数据字节的最有效方法是什么?

先谢谢了, 阿列克谢蓝。

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

4 个答案:

答案 0 :(得分:1)

如果您正在从流中读取图像,则可以创建一个像输入流一样的代理并获取输出流。覆盖read方法,以便在丢失时返回额外丢失的字节。

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

来建立代理

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

PushbackInputStream可能就是您所需要的。

答案 3 :(得分:0)

感谢你们的建议,我最初使用了一个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

希望这可以帮助任何有类似问题的人:)