当前位置:  开发笔记 > 编程语言 > 正文

如何将对象序列化为字符串

如何解决《如何将对象序列化为字符串》经验,为你挑选了3个好方法。

我能够将一个对象序列化为一个文件然后再次恢复它,如下一个代码片段所示.我想将对象序列化为字符串并存储到数据库中.谁能帮我?

LinkedList 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 patches3 = (LinkedList) one;
os.close();

OscarRyz.. 264

塞尔吉奥:

你应该使用BLOB.使用JDBC非常简单.

您发布的第二个代码的问题是编码.您还应该对字节进行编码,以确保它们都不会失败.

如果您仍想将其写入String,则可以使用java.util.Base64对字节进行编码.

仍然应该使用CLOB作为数据类型,因为您不知道序列化数据将会持续多长时间.

以下是如何使用它的示例.

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;
    }
}

输出:

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

注意:对于Java 7及更早版本,您可以在此处查看原始答案



1> OscarRyz..:

塞尔吉奥:

你应该使用BLOB.使用JDBC非常简单.

您发布的第二个代码的问题是编码.您还应该对字节进行编码,以确保它们都不会失败.

如果您仍想将其写入String,则可以使用java.util.Base64对字节进行编码.

仍然应该使用CLOB作为数据类型,因为您不知道序列化数据将会持续多长时间.

以下是如何使用它的示例.

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;
    }
}

输出:

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

注意:对于Java 7及更早版本,您可以在此处查看原始答案


+1,小改进.最好在toString()方法中使用接口Serializable而不是plain Object:private static String toString(Serializable object)
如果我们尝试将对象存储为字节数组而不是字符串,那么我们可以在不使用BASE64的情况下实现相同的功能.
这个致命的缺陷是类定义往往会随着时间的推移而改变 - 如果发生这样的改变,你将无法反序列化!将`serialVersionUID`添加到`SomeClass`将防止添加新字段,但如果字段被删除,您将被搞砸.值得一读的是Joshua Bloch在Effective Java中对此的看法 - http://books.google.co.uk/books?id=ka2VUBqHiWkC&lpg=PP1&dq=effective+java&pg=PA289

2> Outlaw Progr..:

如何将数据写入ByteArrayOutputStream而不是FileOutputStream?

否则,您可以使用XMLEncoder序列化对象,保留XML,然后通过XMLDecoder反序列化.



3> Sergio del A..:

感谢您的快速回复.我会立即给予一些投票,以表示你的帮助.我根据你的答案在我看来编写了最好的解决方案.

LinkedList 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 restored_patches1 = (LinkedList) oInputStream.readObject();            



        // patches1 equals restored_patches1
    oInputStream.close();
} catch(Exception ex) {
    ex.printStackTrace();
}

注意我没有考虑使用JSON,因为效率较低.

注意:我会考虑您的建议,即不将序列化对象存储为数据库中的字符串,而是将byte []替换为.


"ByteArrayOutputStream.toString使用*平台默认编码进行转换*.你确定要这样吗?特别是因为任意字节数组都不是有效的UTF8.此外,数据库会破坏它."
推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有