从字符串中读取对象时StreamCorruptedException

时间:2014-10-20 12:56:50

标签: java android serialization

这是我的代码:

 try {

                Uri uri = Uri.parse("file:///storage/emulated/0/Download/information.csv");
                File file = new File(uri.getPath());
                //Read the file
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line;
                boolean firstLine = true;

                while ((line = br.readLine()) != null) {
                    System.out.println("Print the contents from the file :" + line);
                    if (firstLine) {
                        firstLine = false;
                        continue;
                    } else {

                            //deserialize the string to Object
                            td = TransferData.fromString(line); //Where td is an object 

                            //deserialize the string to Object
                            System.out.println("deserialized: " + td);



               }

但是,我在这一行得到例外:

td = TransferData.fromString(line);

和我的fromString函数:

/** Read the object from Base64 string. */
    public static TransferData fromString( String s ) throws IOException, ClassNotFoundException     {
        byte [] data = Base64.decode(s, Base64.DEFAULT);
        ObjectInputStream ois = new ObjectInputStream(
                new ByteArrayInputStream(  data ) );
        Object o  = ois.readObject();
        ois.close();
        return (TransferData)o;
    }

异常是StreamCorruptedException,但我不确定为什么会这样。我希望能够读取字符串并反序列化字符串。

编辑:

  /** Write the object to a Base64 string. */
    public static String toString(Serializable o) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(output);
        oos.writeObject(o);
        oos.close();
        return new String(Base64.encode(output.toByteArray(), Base64.DEFAULT));
    }



//SerialVersionID
  private static final int serialVersionUID = 10032014;

1 个答案:

答案 0 :(得分:2)

我可以在你的代码中看到一些缺陷:

  1. 每次阅读新行(which is probably causing the StreamCorruptedException
  2. 时,您都在创建新的ObjectInputStream
  3. 如果您通过BufferedReader阅读该文件,则不需要ObjectInputStream反之亦然。
  4. 我无法理解为什么你要做Base64.decode字符串?
  5. 您必须确保serialVersionUID是连贯的。
  6. 如果我理解你想要将对象序列化为文件然后反序列化它。首先,您应该有一个实现Serializable接口的实体(您的对象):

    public class Foo implements Serializable{
        static final long serialVersionUID = 42L;
        //class code...
    }
    

    现在您可以安全地将对象(或其列表)保存到文件中:

    FileOutputStream fos = new FileOutputStream("myFoo.tmp");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    
    Foo foo = new Foo();
    //Fill the object.
    
    oos.writeObject(foo);
    

    如果您需要阅读该文件,您现在可以:

    FileInputStream fis = new FileInputStream("myFoo.tmp");
    ObjectInputStream ois = new ObjectInputStream(fis);
    
    Foo mySavedFoo = (Foo) ois.readObject();
    

    如果您需要保存对象列表,可以使用实现List的{​​{1}} Serializable

    FileOutputStream fos = new FileOutputStream("myFoos.tmp");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    
    List<Foo> foos = new ArrayList<Foo>();
    //Fill the list.
    
    oos.writeObject(foos);
    
    //...
    
    FileInputStream fis = new FileInputStream("myFoos.tmp");
    ObjectInputStream ois = new ObjectInputStream(fis);
    
    ArrayList<Foo> mySavedFoo = (ArrayList<Foo>) ois.readObject();
    

    <强>附录

    当从对象流中读取的控制信息违反内部一致性检查时,<{1}} 抛出

    使用StreamCorruptedException在文件上写入对象时,会添加在反序列化对象时使用的格式正确的标头。如果此标题不一致,则表示您违反了内部一致性检查。

    当您逐行阅读(ObjectOutputStream)文件时,您正在删除此标题,因此line = br.readLine()无法正确阅读您保存的对象。此外,您正在解码ObjectInputStream,从而加扰读取的数据。为您创建的每一行添加一个新的Base64ObjectInputStream


    修改

    从您的编辑中我可以更好地了解您的问题。

    StreamCorruptedException

    就像我之前的例子一样,您通过public static String toString(Serializable o) throws IOException { // what is this? ^ ByteArrayOutputStream output = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(output); oos.writeObject(o); //Here you are saving a Serializable object to... what? Which file? oos.close(); return new String(Base64.encode(output.toByteArray(), Base64.DEFAULT)); } (BTW?)存储Serializable对象,但ObjectOutputStream只是一个接口。如果你使用实现它的类会更好。按照我的例子,它将成为:

    Serializable

    public static String toString(Foo o) throws IOException { //... 完成 AFTER 将对象保存到文件中!!没有&#34;加密&#34;!此外,对Base64.encode output对象进行编码,ByteArrayOutputStream并且与o中存储的实际数据无关。