4

我创建了一个简单的程序,将字符串输入从 cmd 序列化为 .ser 文件。部分要求是程序必须能够附加新输入并能够读取新输入和旧输入。但是我如果我在第二个输入之后阅读,则会得到 StreamCorruptedException ..

这是我在 CMD 上的运行 .. 我该如何解决这个 StreamCorruptedException 以及为什么会发生?代码如下。

C:\Users\MSI\Desktop\Codes For Java>java WriteFile cc.ser
Enter text and press ^Z or ^D to end.
hah
haha
hahaha
try
^Z

C:\Users\MSI\Desktop\Codes For Java>java WriteFile cc.ser
Enter text and press ^Z or ^D to end.
asd
asd
asd
asd
asd
^Z

C:\Users\MSI\Desktop\Codes For Java>java ReadFile cc.ser
1: haha
2: haha
3: hahaha 
4: hahaha
The Error is :
java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1375)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    at ReadFile.main(ReadFile.java:23)

写文件.java:

 import java.io.*;
 public class WriteFile implements java.io.Serializable
 {
public static void main(String args[])  
    {   
        try
        {
           File myFile = new File(args[0]);

           BufferedReader br = new BufferedReader
                                          (new InputStreamReader(System.in));
               ObjectOutputStream oos = new ObjectOutputStream
                                          (new FileOutputStream(myFile,true));

           System.out.println("Enter text and press ^Z or ^D to end.");

           String str;

           while ((str = br.readLine()) != null)

            {

                    oos.writeObject(str);
            }


           br.close();
           oos.close();
        }

        catch (IOException i)
        {
            i.printStackTrace();
        }
}}

读取文件.java:

import java.io.*;
    public class ReadFile
    {       
public static void main(String args[])
    {

        try
        {
        int ctr = 0;

        File myFile = new File(args[0]);

            ObjectInputStream OIS = new ObjectInputStream 
                                               (new FileInputStream( myFile )); 
        String str;



             while ((str = (String)OIS.readObject()) != null)

            {   

               System.out.println(++ctr + ": " + str);

            }

            OIS.close();        
        }

        catch (EOFException ex)
        {
          System.out.println("\nEnd of File Reached ");
        }



        catch (ClassNotFoundException c)
        {
          System.out.println("The Error is : ");
          c.printStackTrace();
        }catch (IOException i)
        {
          System.out.println("The Error is : ");
          i.printStackTrace();
        } 
    }}
4

4 回答 4

1

每当您尝试为现有输入流创建新的 OutputStream 对象/甚至在写入某些内容之前尝试读取时,就会发生此异常,在这种情况下,从对象流中读取的控制信息违反了内部一致性检查。

在套接字的整个生命周期中使用单个 OOS 和 OIS,并且不要在套接字上使用任何其他流。

您也可能希望在同一程序中使用线程来实现相同的功能。

如果您想忘记您所写的内容,请使用 ObjectOutputStream.reset()。

于 2013-08-20T04:40:27.083 回答
0

我在阅读了这个问题的一些答案后编辑了我的代码附加到一个 ObjectOutputStream

import java.io.*;



public class WriteFile
implements java.io.Serializable
{

public static void main(String args[])  
    {

        try
        {
           File myFile = new File(args[0]);

           BufferedReader br = 
                           new BufferedReader(new InputStreamReader(System.in));

           if (myFile.exists())
                {
                   AppendingObjectOutputStream AOOS = new   AppendingObjectOutputStream(new FileOutputStream(myFile,true));                                      
                       System.out.println("Enter text and press ^Z or ^D to end.");

                   String str;

                           while ((str = br.readLine()) != null)

                         {

                             AOOS.writeObject(str);
                         }


                     br.close();
                     AOOS.flush();

                }

         else
          { 
           ObjectOutputStream OOS = new ObjectOutputStream(new FileOutputStream(myFile,true));
           System.out.println("Enter text and press ^Z or ^D to end.");

           String str;

           while ((str = br.readLine()) != null)

            {

                    OOS.writeObject(str);
            }


           br.close();
           OOS.flush();
          }

        }
        catch (IOException i)
        {
            i.printStackTrace();
        }

}}

并从上述问题中添加一个新类

public class AppendingObjectOutputStream extends ObjectOutputStream {

public AppendingObjectOutputStream(OutputStream out) {
  super(out);
}

@Override
protected void writeStreamHeader() throws IOException {
  // do not write a header, but reset:
  // this line added after another question
  // showed a problem with the original
 reset();
}}

有什么建议可以更好地改进此代码?抱歉只是java编程的新手

这是我在 CMD 上的新运行

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。版权所有。

C:\Users\MSI>cmd 'cmd' 不是内部或外部命令、可运行程序或批处理文件。

C:\Users\MSI\Desktop\Codes For Java>java WriteFile haha.ser
Enter text and press ^Z or ^D to end.
a
b
c
d
^Z

C:\Users\MSI\Desktop\Codes For Java>java WriteFile haha.ser
Enter text and press ^Z or ^D to end.
e
f
g
^Z

C:\Users\MSI\Desktop\Codes For Java>java ReadFile haha.ser
1: a
2: b
3: c
4: d
5: e
6: f
7: g

End of File Reached

我没有更改我的 readfile.java 文件...感谢您的回答 =D

于 2013-08-21T06:31:19.777 回答
0

我认为出现此问题是因为您甚至在写入之前就尝试阅读。

于 2013-08-20T16:35:19.100 回答
-1

在开始编写代码并解决编码问题之前,您需要明确几个问题。

1) 为什么需要使用 ObjectInputStream 和 ObjectOutputStream?如果你只是读写字符串,最好使用BufferedWriter和BufferedReader。我们只使用 OIS 和 OOS 来读写对象。

2)您的问题与序列化和反序列化无关。请进行谷歌搜索以了解如何进行正确的序列化和反序列化。在您的代码段中:

public class WriteFile implements java.io.Serializable // there is no meaning to implement the mark up interface here.

简而言之,只在 POJO 或数据对象上标记 java.io.Serializable。

3) 当你按 ctrl-c 或 ctrl-z 时,有一个系统中断信号被触发,整个系统会突然停止,这会导致数据写入的损坏。

我花了一些时间为您编写了一个完整的工作示例。希望你能从我的样本中得到一些东西。

控制台编写器

/**
    * Write Console String to a file
    * When you type quit or save it will write to the file in one go.
    * 
    * @author Seabook Chen
    *
*/
public class SimpleConsoleWriter {
    private static final String NEW_LINE =  System.getProperty("line.separator");

    public static void main(String[] args) {

        if (args == null || args.length == 0) {
            throw new RuntimeException("Please specify the file name!!!");
        }

        String filepath = args[0];

        Scanner in = new Scanner(System.in);
        System.out.println("Please input your comments ....");
        System.out.println("Type quit to finish the input! Please type exact quit to quit!!!");
        System.out.println("Type save to write to the file you specified. ");

        StringBuilder sb = new StringBuilder();
        while(true) {
            String input = in.nextLine();

            if ("quit".equalsIgnoreCase(input) || "save".equalsIgnoreCase(input)) {
                System.out.println("Thanks for using the program!!!");
                System.out.println("Your input is stored in " + filepath);
                break;
            }

            sb.append(input);
            sb.append(NEW_LINE);

        }

        FileWriter fw = null;
        BufferedWriter bw = null;

        try {
            fw = new FileWriter(filepath, true);
            bw = new BufferedWriter(fw);
            bw.write(sb.toString(), 0, sb.toString().length());
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

简单控制台阅读器

/**
 * Read a file and output in the console 
 * 
 * @author Seabook Chen
 *
 */
public class SimpleConsoleReader {
    public static void main(String[] args) {
        if (args == null || args.length == 0) {
            throw new RuntimeException("Please specify the file name!!!");
        }
        File file = new File(args[0]);
        FileReader fr = null;
        BufferedReader br = null;
        String nextLine = null;
        try {
            fr = new FileReader(file);
            br = new BufferedReader(fr);

            while((nextLine = br.readLine()) != null ) {
                System.out.println(nextLine);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
于 2013-08-20T07:24:07.860 回答