¿Cuál es la forma más eficiente de agregar datos a la mitad de un flujo de bytes?

He estado haciendo un reescalador de imágenes que usa la biblioteca ImageIO en Java para convertirlos en una imagen almacenada en búfer. Desafortunadamente, no reconoce todos los tipos de JPEG que puedo pasarle, por lo que necesito "convertir" estos otros tipos. La forma en que los estoy convirtiendo es tomando una etiqueta APP0 existente de un JFIF JPEG estándar y lo que quiero hacer es en el tercer byte en el archivo, inserte 3 bytes de datos (el marcador FFE18 y la etiqueta APP0 de 16 bytes) y luego quiero agregar el resto del archivo al final de eso.

Entonces, para generalizar, ¿cuál es la forma más eficiente de agregar / insertar bytes de datos a la mitad de una secuencia / archivo?

Gracias de antemano, Alexei Blue.

Esta pregunta está vinculada a una pregunta mía anterior, por lo que me gustaría agradecer a onemasse por la respuesta que se dio allí. Convertidor Java JPEG para tipos de imágenes impares

preguntado el 08 de noviembre de 11 a las 12:11

4 Respuestas

Si está leyendo sus imágenes de un flujo, puede crear un proxy que actúe como un flujo de entrada y tome un flujo de salida. Anule el método de lectura para que devuelva los bytes extra que faltan cuando faltan.

Se puede crear un proxy extendiendo FilterInputStream http://download.oracle.com/javase/6/docs/api/java/io/FilterInputStream.html

respondido 08 nov., 11:16

Si es un archivo, la forma recomendada de hacerlo es copiar el archivo existente a uno nuevo, insertando, cambiando o eliminando bytes en los puntos apropiados. Luego cambie el nombre del nuevo archivo por el anterior.

En teoría, podría intentar usar RandomAccessFile (o equivalente) para realizar una actualización in situ de un archivo existente. Sin embargo, es un poco complicado, no tan eficiente como podría imaginar y ... lo más importante ... no es seguro. (Si su aplicación o el sistema muere en un momento inoportuno, se queda con un archivo roto y no hay forma de recuperarlo).

respondido 08 nov., 11:16

A PushbackInputStream podría ser lo que necesitas.

respondido 09 nov., 11:02

Gracias por la sugerencia, chicos, usé un FilterInputStream al principio pero luego vi que no era necesario, usé el siguiente código para ingresar mi etiqueta APP0 Hex en:

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

Y en el método de conversión deseado:

        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

Espero que esto ayude a cualquiera que tenga un problema similar :)

respondido 21 nov., 11:18

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.