我一直在制作一个图像重新缩放器,它使用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
希望这有助于任何人有类似的问题:)