2015-10-06 89 views
0

我有一個方法,將int存儲在.dat文件中(除此之外),稍後我嘗試使用其他方法檢索該文件,並給出了一個荒謬的值。例如,如果我嘗試存儲1,則另一個方法將檢索到484449.我是Java新手,如果這是正常的,請解釋。ReadInt()返回荒謬值

方法寫入INT:

public static int fromText (String textRefference, String binaryRefference, 
      boolean overwrite, String countRefference){ 

     if(!(new File(binaryRefference).exists()))overwrite = true; 
     BufferedReader input; 
     ObjectOutputStream output; 
     ObjectInputStream binaryInput; 
     ObjectInputStream countStreamI; 
     ObjectOutputStream countStreamO; 
     int count = 0; 

     try{ 
      input = new BufferedReader(new FileReader(textRefference)); 
      String[] data = null; 
      int oldCount = 0; 
      if(!overwrite){ 
       countStreamI = new ObjectInputStream(new FileInputStream(countRefference)); 
       binaryInput = new ObjectInputStream(new FileInputStream(binaryRefference)); 
       oldCount = countStreamI.readInt(); 
       data = new String[oldCount]; 
       int i; 
       for(i = 0;i < oldCount; i++){ 

        data[i] = binaryInput.readUTF(); 

       } 
       countStreamI.close(); 
      } 

      countStreamO = new ObjectOutputStream(new FileOutputStream(countRefference)); 
      output = new 
        ObjectOutputStream(new FileOutputStream(binaryRefference)); 

      String sentinel = input.readLine(); 
      String[] data2 = new String[1500]; 
      while(!sentinel.equalsIgnoreCase("end")){ 

       System.out.println(sentinel + " has been recorded"); 
       data2[count] = sentinel; 
       sentinel = input.readLine(); 
       count++; 

      } 

      count += oldCount; 
      countStreamO.writeInt(count); 

      if(!overwrite){ 

       int i; 
       for(i = 0; i < oldCount;i++){ 

        output.writeUTF(data[i]); 

       } 

      } 

      int i = 0; 
      for(; i < count + oldCount;i++){ 

       output.writeUTF(data2[i]); 

      } 

      output.flush(); 
      countStreamO.flush(); 
      countStreamO.close(); 
      output.close(); 
      input.close(); 

     } 

     catch(Exception e){ 
      Scanner in = new Scanner(System.in); 
      e.printStackTrace(); 
      in.nextLine(); 
      System.exit(0); 
     } 
     return count; 
    }' 

,功能取回:

public static String[] pullStrings(String file, String countReferrence, boolean print){ 

     String[] data = null; 

     try{ 

      ObjectInputStream input = new ObjectInputStream(new FileInputStream(file)); 
      int count = input.readInt(); 
      data = new String[count]; 
      int i = 0; 
      String string; 
      for(;i < count; i++){ 

       string = input.readUTF(); 
       if(print)System.out.println(string); 
       data[i] = string; 

      } 
     } 
     catch(Exception e){ 
      Scanner in = new Scanner(System.in); 
      System.out.println(e.getMessage() + "\n\n"); 
      e.printStackTrace(); 
      System.out.println("\n hit ENTER to exit."); 
      in.nextLine(); 
      System.exit(0); 
     } 

     return data; 

    } 

而且文本文件:

data!!! 

end 
+4

你的問題基本上是,'「這是爲什麼我不顯示你不工作的代碼?」'。請通過創建併發布您的[mcve]來解決此問題。 –

+0

如果出現錯誤,請務必發佈您的代碼和錯誤。一個簡單的描述不足以幫助你 –

+0

你可以與我們分享功能嗎?沒有代碼示例,真的很難幫助你。 – wmk

回答

0

這你要怪號,484449 ,實際上是讀取四個字節的結果:00 07 64 61.

這些字節來自哪裏?那麼,出於某種原因,你選擇發送count不同的文件,使用countStreamO.writeInt(count);。所以當你的檢索代碼執行input.readInt()時,它希望在同一個文件中找到一個計數,但你從來沒有在那裏寫過計數。

而是將計數發送到不同的文件,然後使用output.writeUTF(data[i])output.writeUTF(data2[i])繼續將每個字符串寫入主數據文件。

writeUTF實際上做了什麼?那麼,ObjectOutputStream.writeUTF的文檔並沒有多說,除了該方法是由DataOutput接口強制的。所述documentation for DataOutput.writeUTF是相當翔實,雖然:

將兩個字節寫入的長度信息到輸出流,後跟字符串s中的每個字符的UTF-8修改表示。

因此,您從未將count值寫入文件,但您確實發送了字符串「data !!!」到它。現在我們知道writeUTF首先將該字符串的字節長度(在將其轉換爲修改後的UTF-8後)寫入,後面跟着修改後的UTF-8字節本身。

在這種情況下,您的字符串完全由ASCII字符組成,當以修改後的UTF-8(或真正的UTF-8)進行編碼時,每個字節佔用一個字節,無需編碼。所以字符串需要7個字節,每個字符一個字節。

意思是,writeUTF方法爲字節長度(00 07)寫了兩個字節,後面跟着字符(64 61 74 61 21 21 21)的七個字節。

這意味着該文件中的前四個字節是00 07 64 61.你想讀他們作爲32位int,所以你得到0x00076461,或484449.

你的代碼是遠比它需要更復雜。這種複雜性使得很難看到像這樣的小問題。另外,有些文檔會說明你的代碼應該做什麼。看起來您已經意識到,當您開始編寫檢索代碼時,您並不需要單獨的計數文件,但您永遠不會回頭並更新寫入數據以適應改進的代碼。

我不知道,如果你的數據文件需要堅持外部指定的格式,但如果沒有,你可以很容易地通過去除完全計數,並與和的readUTF做writeUTF客場完成你的任務。取而代之的是,可以簡單序列字符串數組:

String[] allData = new String[data.length + data2.length]; 
System.arraycopy(data, 0, allData, 0, data.length); 
System.arraycopy(data2, 0, allData, data.length, data2.length); 

try (ObjectOutputStream out = new ObjectOutputStream(
     new BufferedOutputStream(
      new FileOutputStream(binaryReference)))) { 
    out.write(allData); 
} 

長度陣列對象的狀態的一部分,所以它被包含在串行化輸出。

閱讀它更容易:

String[] data; 
try (ObjectInputStream in = new ObjectInputStream(
     new BufferedInputStream(
      new FileInputStream(file)))) { 
    data = (String[]) in.readObject(); 
}