sirve serializacion que para objetos guardar deserializacion clase archivos java objectinputstream objectoutputstream

serializacion - implements serializable java



¿Por qué solo puedo leer 1024 bytes a la vez con ObjectInputStream? (3)

Le sugiero que use una declaración try-with-resources para controlar el cierre de sus recursos, agregue el búfer con BufferedInputStream y BufferedOutputStream , y luego use writeObject y readObject para serializar su byte[] . Algo como,

try (OutputStream output = new BufferedOutputStream(// new FileOutputStream("test.txt"), 8192); // ObjectOutputStream stream = new ObjectOutputStream(output)) { byte[] bytes = new byte[4000]; stream.writeObject(bytes); } catch (IOException ioe) { ioe.printStackTrace(); }

y luego leer como

try (InputStream input = new BufferedInputStream(// new FileInputStream("test.txt"), 8192); // ObjectInputStream s = new ObjectInputStream(input)) { byte[] bytes = (byte[]) s.readObject(); } catch (IOException | ClassNotFoundException ioe) { ioe.printStackTrace(); }

Si hay matrices parciales involucradas, necesitarás agregar la longitud. Puedes usar stream.writeInt(len); y int len = stream.readInt(); Por otro lado.

He escrito el siguiente código que escribe 4000 bytes de 0s en un archivo test.txt . Luego, leí el mismo archivo en trozos de 1000 bytes a la vez.

FileOutputStream output = new FileOutputStream("test.txt"); ObjectOutputStream stream = new ObjectOutputStream(output); byte[] bytes = new byte[4000]; stream.write(bytes); stream.close(); FileInputStream input = new FileInputStream("test.txt"); ObjectInputStream s = new ObjectInputStream(input); byte[] buffer = new byte[1000]; int read = s.read(buffer); while (read > 0) { System.out.println("Read " + read); read = s.read(buffer); } s.close();

Lo que espero que suceda es leer 1000 bytes cuatro veces.

Read 1000 Read 1000 Read 1000 Read 1000

Sin embargo, lo que realmente sucede es que parece que me "detienen" (por falta de una palabra mejor) cada 1024 bytes.

Read 1000 Read 24 Read 1000 Read 24 Read 1000 Read 24 Read 928

Si trato de leer más de 1024 bytes, entonces tengo un límite de 1024 bytes. Si intento leer menos de 1024 bytes, todavía debo hacer una pausa en la marca de 1024 bytes.

Al inspeccionar el archivo de salida test.txt en hexadecimal, noté que hay una secuencia de 5 bytes distintos de cero 7A 00 00 04 00 1029 bytes aparte, a pesar del hecho de que solo he escrito 0s en el archivo. Aquí está la salida de mi editor hexadecimal. (Sería demasiado largo para caber en cuestión.)

Así que mi pregunta es: ¿por qué aparecen estos cinco bytes en mi archivo cuando escribí 0s en su totalidad? ¿Estos 5 bytes tienen algo que ver con la pausa que ocurre cada 1024 bytes? ¿Por qué es esto necesario?


Los flujos de objetos utilizan un búfer interno de 1024 bytes y escriben datos primitivos en trozos de ese tamaño, en bloques del flujo encabezado por marcadores de datos de bloque, que son, adivina qué, 0x7A seguido de una palabra de longitud de 32 bits (o 0x77 seguido por una palabra de longitud de 8 bits). Por lo tanto, solo se puede leer un máximo de 1024 bytes.

La pregunta real aquí es por qué estás usando flujos de objetos solo para leer y escribir bytes. Utilice flujos de búfer. Luego, el almacenamiento en búfer está bajo su control, e incidentalmente no hay sobrecarga de espacio, a diferencia de los flujos de objetos que tienen encabezados de flujo y códigos de tipo.

Los datos serializados de NB no son texto y no deben almacenarse en archivos llamados .txt.


ObjectOutputStream y ObjectInputStream son flujos especiales que se utilizan para la serialización de objetos.

Pero cuando haces stream.write(bytes); está intentando usar ObjectOutputStream como un flujo regular, para escribir 4000 bytes, no para escribir un objeto de matriz de bytes. Cuando los datos se escriben de este modo en un ObjectOutputStream , se manejan especialmente.

De la documentación de ObjectOutputStream :

(énfasis mío).

Los datos primitivos, excluidos los campos serializables y los datos externalizables, se escriben en ObjectOutputStream en registros de datos de bloque. Un registro de datos de bloque se compone de un encabezado y datos. El encabezado de datos de bloque consiste en un marcador y el número de bytes que siguen al encabezado. Escrituras de datos primitivos consecutivos se combinan en un registro de datos de bloque. El factor de bloqueo utilizado para un registro de datos de bloque será de 1024 bytes . Cada registro de datos de bloque se llenará hasta 1024 bytes, o se escribirá siempre que haya una terminación del modo de datos de bloque.

Espero que de esto sea obvio por qué está recibiendo este comportamiento.

Le recomendaría que use BufferedOutputStream lugar de ObjectOutputStream o, si realmente desea usar ObjectOutputStream , luego use writeObject() lugar de write() . Lo correspondiente se aplica a la entrada.