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



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

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

提前感谢,阿列克谢蓝色。

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

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

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

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

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

PushbackInputStream可能就是你需要的。

谢谢你的建议,我一开始使用了FilterInputStream,但后来发现没有必要,我使用以下代码来输入我的APP0十六进制标签:

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

希望这有助于任何人有类似的问题:)

最新更新