2014-04-06 32 views
2

我正在使用FileInputStream以文件的字節數讀取。代碼(在其正確的形式)如下:閱讀完所有的文件,並把每一組的4 bytesfloat當使用String.valueOf或Float.toString時,爲什麼這個循環變得無限?

String s = ""; 
try { 
     File file = new File(...); 
     FileInputStream file_input = new FileInputStream(file); 
     DataInputStream data_in = new DataInputStream(file_input); 

     while (true) { 
      try { 
       for (int index = 0; index < 4; index++) { 
        byteArray[index] = data_in.readByte(); 
       }   
      } catch (EOFException eof) { 
       break; 
      } 

      float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float 
      //s += Float.toString(f); <- here's the problem 
     } 
     data_in.close(); 
    } catch (IOException e) { 
     System.err.println(e.toString()); 
    } 
} 
System.out.print(s); 

如果我爲這段代碼運行,則循環結束。

但是,如果我取消註釋該行,該文件永遠不會結束,似乎一遍又一遍地遍歷文件。此外,打印f(不使用Float.toStringString.valueOf)不會將其變成無限循環。

+2

你有什麼證據表明它是一個無限循環(而不是慢)? –

+0

我包含一個文件大小的計數器,並遞增計數器循環執行的次數。如果計數器大於此大小,我將它重置爲零,並輸出另一個計數器,顯示發生了多少次。當我這樣做,它打印1 2 3 4 ...並不停止。 – user473973

+0

你是否嘗試用'catch(Exception e)'替換'catch(EOFException eof)',僅用於調試目的? (也許會引發另一個異常) – xav

回答

1

循環不會變得無限 - 只是非常低效。 java.lang.String上的+=的問題在於它產生了一個新的不可變對象,放棄了它之前保存的對象。每次複製時,根據文件中的條目數量將過程設置爲O(n )。

修復很簡單 - 將String s替換爲StringBuilder s,並使用append代替+=

StringBuilder s = new StringBuilder(); 
try { 
    File file = new File(...); 
    FileInputStream file_input = new FileInputStream(file); 
    DataInputStream data_in = new DataInputStream(file_input); 
    while (true) { 
     try { 
      for (int index = 0; index < 4; index++) { 
       byteArray[index] = data_in.readByte(); 
      }   
     } catch (EOFException eof) { 
      break; 
     } 
     float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float 
     s.append(f); 
    } 
    data_in.close(); 
} catch (IOException e) { 
    System.err.println(e.toString()); 
} 
System.out.print(s); 
+1

另一個字符串連接的例子並非真空,而且確實會影響性能。謝謝! – user473973