¿Cómo arreglar java.io.StreamCorruptedException: código de tipo no válido en Java?

Se han enfrentado varios problemas que son los siguientes:

  1. Cuando escribe un objeto en un archivo utilizando la serialización en Java por primera vez, no surge ningún problema para leer el archivo después, incluso cuando escribe varios objetos de una sola vez.
  2. Ahora, la próxima vez que intente agregar nuevos objetos (del mismo tipo) a ese archivo mediante la serialización, la escritura del archivo se realizará correctamente sin ningún error.
  3. Pero leer el archivo creará un problema y se lanzará una excepción llamada StreamCorruptedException.

La causa raíz detrás de estos problemas o podemos decir las razones son las siguientes:

  1. Cada vez que abrimos un archivo e intentamos agregar un objeto serializable al final del archivo usando ObjectOutputStream y FileOutputStream, ObjectOutputStream escribirá el encabezado al final del archivo para escribir los datos del objeto. Cada vez que se abre el archivo y se escribe el primer objeto, ObjectOutputStream escribirá el encabezado al final del archivo antes de escribir los datos del objeto.
  2. Entonces, de esta manera, el encabezado se escribe varias veces cada vez que el archivo se abre en modo de adición para escribir el objeto usando FileOutputStream y ObjectOutputStream.

Para solucionar estos problemas, se deben implementar varias medidas de la siguiente manera: 

  1. Cree su propia clase de flujo de salida de objetos, digamos la clase MyObjectOutputStream , extendiendo ObjectOutputStream (herencia) y anule el método: » protected void writeStreamHeader() throws IOException «. En su nueva clase, este método no debería hacer nada.
  2. Ahora, cuando escribe Objeto por primera vez, es decir, cuando la longitud del archivo es 0, use el objeto de la clase predefinida ObjectOutputStream, para escribir el objeto usando writeObject().
  3. Esto escribirá el encabezado en el archivo al principio.

La próxima vez que escriba el objeto, es decir, cuando la longitud del archivo sea > 0, use el objeto de su clase definida MyObjectOutputStream, para escribir el objeto usando writeObject(). Como ha anulado el método writeStreamHeader() y no hace nada, el encabezado no se volverá a escribir en el archivo.

Implementación:

Aquí, para optimizar el programa, para comprenderlo de una vez, tendremos 3 archivos de clase java diferentes correspondientes a sus clases java ejecutables

  1. CustomerCollection.java
  2. Cliente.java
  3. Principal.java

Ejemplo 1: CustomerCollection.java

Java

// Java program to illustrate CustomerCollection.java
 
// Importing input output classes
import java.io.*;
// Importing utility classes
import java.util.*;
 
// Class 1
// helper class
class MyObjectOutputStream extends ObjectOutputStream {
 
    // Constructor of this class
    // 1. Default
    MyObjectOutputStream() throws IOException
    {
 
        // Super keyword refers to parent class instance
        super();
    }
 
    // Constructor of this class
    // 1. Parameterized constructor
    MyObjectOutputStream(OutputStream o) throws IOException
    {
        super(o);
    }
 
    // Method of this class
    public void writeStreamHeader() throws IOException
    {
        return;
    }
}
 
// Class 2
// Helper class
public class CustomerCollection {
 
    // Getting file from local machine by creating
    // object of File class
    private static File f = new File("BankAccountt.txt");
 
    // Method 1
    // To read from the file
    public static boolean readFile()
    {
        // Initially setting bool value as false
        boolean status = false;
 
        // Try block to check for exceptions
        try {
 
            // Creating new file using File object above
            f.createNewFile();
        }
 
        // Catch block to handle the exception
        catch (Exception e) {
        }
 
        // If the file is empty
        if (f.length() != 0) {
 
            try {
 
                // If file doesn't exists
                FileInputStream fis = null;
 
                fis = new FileInputStream(
                    "BankAccountt.txt");
                ObjectInputStream ois
                    = new ObjectInputStream(fis);
 
                Customer c = null;
 
                while (fis.available() != 0) {
                    c = (Customer)ois.readObject();
                    long accNo = c.getAccountNumber();
 
                    // Print customer name and account
                    // number
                    System.out.println(c.getCustomerName()
                                       + " & ");
                    System.out.println(
                        c.getAccountNumber());
                }
 
                // Closing the connection to release memory
                // resources using close() method
                ois.close();
                fis.close();
 
                // Once all connection are closed after the
                // desired action change the flag state
                status = true;
            }
 
            // Catch block to handle the exception
            catch (Exception e) {
 
                // Print the exception on the console
                // along with display message
                System.out.println("Error Occurred" + e);
 
                // Exception encountered line is also
                // displayed on console using the
                // printStackTrace() method
                e.printStackTrace();
            }
        }
        return status;
    }
 
    // Method 2
    // To add a new customer
    public static boolean AddNewCustomer(Customer c)
    {
        // again, setting and initializing the flag boolean
        // value
        boolean status = false;
 
        // If customer is not present
        if (c != null) {
            // try block to check for exception
            try {
 
                // Initially assigning the object null to
                // avoid GC involvement
                FileOutputStream fos = null;
 
                // Creating an new FileOutputStream object
                fos = new FileOutputStream(
                    "BankAccountt.txt", true);
 
                // If there is nothing to be write onto file
                if (f.length() == 0) {
                    ObjectOutputStream oos
                        = new ObjectOutputStream(fos);
                    oos.writeObject(c);
                    oos.close();
                }
 
                // There is content in file to be write on
                else {
 
                    MyObjectOutputStream oos = null;
                    oos = new MyObjectOutputStream(fos);
                    oos.writeObject(c);
 
                    // Closing the FileOutputStream object
                    // to release memory resources
                    oos.close();
                }
 
                // Closing the File class object to avoid
                // read-write
                fos.close();
            }
 
            // Catch block to handle the exceptions
            catch (Exception e) {
 
                // Print the exception along with the
                // display message
                System.out.println("Error Occurred" + e);
            }
 
            // Change the flag status
            status = true;
        }
 
        return status;
    }
}

Por ahora , guarde este código en un archivo CustomerCollection.java

Ejemplo 2: Cliente.java  

Java

// Java program of Customer.java
import java.io.*;
 
class Customer implements Serializable {
    // Private class variables
    private String name;
    private long acc_No;
 
    // Class Constructor
    Customer(String n, long id)
    {
        acc_No = id;
        name = n;
    }
 
    // Getter methods of class variables
    public String getCustomerName() { return name; }
    public long getAccountNumber() { return acc_No; }
}

 
Por ahora , guarde este código en un archivo Customer.java

Ejemplo 3: Main.java 

Java

// Java Program to illustrate Main.java
 
// Importing input output classes
import java.io.*;
 
// Main class
// Here all above helper classes comes into play
public class Main {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Class objects assigned with constructors
        // Customer input entries
        Customer c1 = new Customer("Rita", 1);
        Customer c2 = new Customer("Sita", 2);
 
        // Adding new customers as created above
        CustomerCollection.AddNewCustomer(c1);
        CustomerCollection.AddNewCustomer(c2);
 
        // Display message for better readability and
        // understanding
        System.out.println("****Reading File****");
 
        // Lastly reading File
        CustomerCollection.readFile();
    }
}

Por ahora , guarde este código en un archivo Main.java

Salida: después de guardar los 3 archivos, ejecute el programa 

Nota: La salida será diferente después de las pruebas de ejecución sucesivas. 

Ejecución 1: cuando el programa se ejecuta por primera vez, el resultado es el siguiente:

****Reading File****
Rita & 1
Sita & 2

Ejecución 2: Nuevamente, cuando se ejecuta el programa anterior, hay una diferencia y el resultado es el siguiente:

****Reading File****
Rita & 1
Sita & 2
Rita & 1
Sita & 2

Explicación de salida:

El resultado es así porque ya en la primera vez, estos 2 objetos (con el nombre de Rita y Sita) se escribieron en el archivo llamado «BankAccountt.txt» y cuando ejecuta el código por segunda vez, nuevamente se agregan los mismos 2 objetos en el archivo.

Publicación traducida automáticamente

Artículo escrito por sameekshakhandelwal1712 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *