2013-08-20 198 views
4

我創建了一個簡單的程序,將字符串輸入從cmd序列化爲.ser文件。部分要求是程序必須能夠追加新輸入並能夠讀取新輸入舊的輸入..但我得到StreamCorruptedException如果我讀後第二次輸入..java序列化和反序列化

這裏是我在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) 

WriteFile.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(); 
     } 
}} 

ReadFile.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(); 
     } 
    }} 
+0

[StreamCorruptedException:無效類型代碼:AC]的可能重複(http://stackoverflow.com/問題/ 2393179/streamcorruptedexception-無效型碼-AC)追加到一個ObjectOutputStream]的 –

+0

可能重複(http://stackoverflow.com/questions/1194656/appending-to-an-objectoutputstream) – SimonC

+0

'的readObject() '在流結束時不返回空值。你應該爲這種情況捕捉'EOFException'。 – EJP

回答

1

每當你企圖創建一個新的OutputStream對象爲現有的輸入流/努力,就會出現此異常甚至在寫入內容之前讀取,在這種情況下,從對象流讀取的控制信息違反內部一致性檢查。

在套接字的生命週期中使用單個OOS和OIS,並且不要在套接字上使用任何其他流。

另外你可能想在同一個程序中使用線程來實現相同的功能。

如果您想忘記所寫的內容,請使用ObjectOutputStream.reset()。

-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,有一個系統中斷信號觸發,整個系統將突然停止,這將導致數據寫入的腐敗。

我花了一點時間爲您編寫完整的工作示例。希望你能從我的樣本中獲得某些東西。

ConsoleWriter

/** 
    * 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(); 
       } 
      } 
     } 


    } 
} 

SimpleConsoleReader

/** 
* 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(); 
       } 
      } 
     } 
    } 
} 
+0

「您的問題與序列化無關」錯誤。您的'ConsoleWriter'示例沒有檢查'readLine()'結果爲null,因此會拋出'NullPointerExceptions'。答案大多不相關。 -1 – EJP

+0

我不知道你爲什麼給我投票?我花了30分鐘來編寫程序來幫助回答問題,沒有人表示讚賞。代碼中可能存在錯誤。這只是一個快速演示。無論如何,讓它成爲。 – Seabook

+0

我再次檢查了我的代碼。沒有NPE,所以你永遠不會運行我的代碼,只是猜測。無論如何,我沒有太多的話要說。 – Seabook

0

我覺得出現這個問題,因爲你企圖被寫入甚至前必讀。

0

我編輯我的代碼從上面

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

更好地完善這個代碼的任何建議中提到的問題,閱讀一些這個問題的答案Appending to an 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(); 
     } 

}} 

,並添加新的下課?對不起只是一個新手Java編程

這裏是我在CMD

的Microsoft Windows新的運行[版本6.1.7601] 版權所有(C)2009年微軟公司。版權所有。

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 

我did'nt改變我readfile.java文件...感謝您的答案= d