una serializar serializacion readobject guardar como clase java serialization

serializar - serializable java 8



Cómo serializar un objeto en una cadena (13)

Puedo serializar un objeto en un archivo y luego restaurarlo nuevamente como se muestra en el siguiente fragmento de código. Me gustaría serializar el objeto en una cadena y almacenarlo en una base de datos. ¿Alguien puede ayudarme?

LinkedList<Diff_match_patch.Patch> patches = // whatever... FileOutputStream fileStream = new FileOutputStream("foo.ser"); ObjectOutputStream os = new ObjectOutputStream(fileStream); os.writeObject(patches1); os.close(); FileInputStream fileInputStream = new FileInputStream("foo.ser"); ObjectInputStream oInputStream = new ObjectInputStream(fileInputStream); Object one = oInputStream.readObject(); LinkedList<Diff_match_patch.Patch> patches3 = (LinkedList<Diff_match_patch.Patch>) one; os.close();


¿Qué hay de escribir los datos en un ByteArrayOutputStream en lugar de un FileOutputStream?

De lo contrario, podría serializar el objeto usando XMLEncoder, persistir el XML, luego deserializar a través de XMLDecoder.


¿Qué hay de persistir el objeto como una blob


Eche un vistazo a la clase java.sql.PreparedStatement, específicamente la función

http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setBinaryStream(int,%20java.io.InputStream)

Luego eche un vistazo a la clase java.sql.ResultSet, específicamente la función

http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#getBinaryStream(int)

Tenga en cuenta que si está serializando un objeto en una base de datos, y luego cambia el objeto en su código en una nueva versión, el proceso de deserialización puede fallar fácilmente debido a que la firma de su objeto cambió. Una vez cometí este error al almacenar una Preferencia personalizada serializada y luego hacer un cambio a la definición de Preferencias. De repente, no pude leer ninguna de las informaciones previamente serializadas.

Puede ser mejor escribir columnas torpes por propiedad en una tabla y componer y descomponer el objeto de esta manera en su lugar, para evitar este problema con las versiones de objetos y la deserialización. O escribir las propiedades en un hashmap de algún tipo, como un objeto java.util.Properties, y luego serializar el objeto de propiedades que es muy poco probable que cambie.


Enfoque Java8, conversión de Object from / to String, inspirado en la respuesta de OscarRyz . Para des / codificación, java.util.Base64 es requerido y utilizado.

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Base64; import java.util.Optional; interface ObjectHelper { static Optional<String> convertToString(final Serializable object) { try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos)) { oos.writeObject(object); return Optional.of(Base64.getEncoder().encodeToString(baos.toByteArray())); } catch (final IOException e) { e.printStackTrace(); return Optional.empty(); } } static <T extends Serializable> Optional<T> convertFrom(final String objectAsString) { final byte[] data = Base64.getDecoder().decode(objectAsString); try (final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) { return Optional.of((T) ois.readObject()); } catch (final IOException | ClassNotFoundException e) { e.printStackTrace(); return Optional.empty(); } } }


Gracias por respuestas geniales y rápidas. Daré algunos votos inmediatamente para agradecer su ayuda. En mi opinión, he codificado la mejor solución en función de sus respuestas.

LinkedList<Patch> patches1 = diff.patch_make(text2, text1); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream os = new ObjectOutputStream(bos); os.writeObject(patches1); String serialized_patches1 = bos.toString(); os.close(); ByteArrayInputStream bis = new ByteArrayInputStream(serialized_patches1.getBytes()); ObjectInputStream oInputStream = new ObjectInputStream(bis); LinkedList<Patch> restored_patches1 = (LinkedList<Patch>) oInputStream.readObject(); // patches1 equals restored_patches1 oInputStream.close(); } catch(Exception ex) { ex.printStackTrace(); }

Tenga en cuenta que no consideré usar JSON porque es menos eficiente.

Nota: consideraré su consejo sobre no almacenar objetos serializados como cadenas en la base de datos, sino byte [] en su lugar.


La secuencia serializada es solo una secuencia de bytes (octetos). Entonces la pregunta es cómo convertir una secuencia de bytes a una Cadena, y viceversa. Además, necesita utilizar un conjunto limitado de códigos de caracteres si se va a almacenar en una base de datos.

La solución obvia al problema es cambiar el campo a un LOB binario. Si quieres quedarte con un LOB characer, entonces necesitarás codificar en algún esquema como base64, hex o uu.


Puede usar la construcción en las clases sun.misc.Base64Decoder y sun.misc.Base64Encoder para convertir los datos binarios de serialize en una cadena. Usted no necesita clases adicionales porque están integradas.


Sergio:

Deberías usar BLOB . Es bastante directo con JDBC.

El problema con el segundo código que publicaste es la codificación. También debe codificar los bytes para asegurarse de que ninguno de ellos falle.

Si aún desea escribirlo en una Cadena, puede codificar los bytes usando java.util.Base64 .

Aún así, debería usar CLOB como tipo de datos porque no sabe por cuánto tiempo van a estar los datos serializados.

Aquí hay una muestra de cómo usarlo.

import java.util.*; import java.io.*; /** * Usage sample serializing SomeClass instance */ public class ToStringSample { public static void main( String [] args ) throws IOException, ClassNotFoundException { String string = toString( new SomeClass() ); System.out.println(" Encoded serialized version " ); System.out.println( string ); SomeClass some = ( SomeClass ) fromString( string ); System.out.println( "/n/nReconstituted object"); System.out.println( some ); } /** Read the object from Base64 string. */ private static Object fromString( String s ) throws IOException , ClassNotFoundException { byte [] data = Base64.getDecoder().decode( s ); ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream( data ) ); Object o = ois.readObject(); ois.close(); return o; } /** Write the object to a Base64 string. */ private static String toString( Serializable o ) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos ); oos.writeObject( o ); oos.close(); return Base64.getEncoder().encodeToString(baos.toByteArray()); } } /** Test subject. A very simple class. */ class SomeClass implements Serializable { private final static long serialVersionUID = 1; // See Nick''s comment below int i = Integer.MAX_VALUE; String s = "ABCDEFGHIJKLMNOP"; Double d = new Double( -1.0 ); public String toString(){ return "SomeClass instance says: Don''t worry, " + "I''m healthy. Look, my data is i = " + i + ", s = " + s + ", d = " + d; } }

Salida:

C:/samples>javac *.java C:/samples>java ToStringSample Encoded serialized version rO0ABXNyAAlTb21lQ2xhc3MAAAAAAAAAAQIAA0kAAWlMAAFkdAASTGphdmEvbGFuZy9Eb3VibGU7T AABc3QAEkxqYXZhL2xhbmcvU3RyaW5nO3hwf////3NyABBqYXZhLmxhbmcuRG91YmxlgLPCSilr+w QCAAFEAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cL/wAAAAAAAAdAAQQUJ DREVGR0hJSktMTU5PUA== Reconstituted object SomeClass instance says: Don''t worry, I''m healthy. Look, my data is i = 2147483647, s = ABCDEFGHIJKLMNOP, d = -1.0

NOTA : para Java 7 y versiones anteriores, puede ver la respuesta original aquí


Si está almacenando un objeto como datos binarios en la base de datos, entonces debería usar un tipo de datos BLOB . La base de datos puede almacenarla de manera más eficiente, y usted no tiene que preocuparse por codificaciones y cosas por el estilo. JDBC proporciona métodos para crear y recuperar blobs en términos de secuencias. Use Java 6 si puede, hizo algunas adiciones a la API de JDBC que hacen que lidiar con blobs sea mucho más fácil.

Si necesita almacenar los datos como String, recomendaría XStream para almacenamiento basado en XML (mucho más fácil que XMLEncoder ), pero las representaciones de objetos alternativos podrían ser igualmente útiles (por ejemplo, JSON). Su enfoque depende de por qué realmente necesita almacenar el objeto de esta manera.


Solución simple, funcionó para mí

public static byte[] serialize(Object obj) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream os = new ObjectOutputStream(out); os.writeObject(obj); return out.toByteArray(); }



XStream proporciona una utilidad simple para serializar / deserializar a / desde XML, y es muy rápido. Almacenar CLOB XML en lugar de BLOBS binarios va a ser menos frágil, por no mencionar más legible.


puedes usar UUEncoding