2011-07-02 92 views
6

我對Java比較陌生,我試圖編寫一個簡單的android應用程序。我的應用程序的資產文件夾中有大約3500行的大文本文件,我需要將它讀入字符串中。我找到了一個很好的例子,說明如何做到這一點,但我有一個問題,爲什麼字節數組被初始化爲1024.我不想將它初始化爲我的文本文件的長度?另外,我不想使用char,而不是byte?這裏是代碼:爲什麼初始化這個字節數組爲1024

private void populateArray(){ 
    AssetManager assetManager = getAssets(); 
    InputStream inputStream = null; 
    try { 
     inputStream = assetManager.open("3500LineTextFile.txt"); 
    } catch (IOException e) { 
     Log.e("IOException populateArray", e.getMessage()); 
    } 
    String s = readTextFile(inputStream); 
    // Add more code here to populate array from string 
} 

private String readTextFile(InputStream inputStream) { 
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    inputStream.length 
    byte buf[] = new byte[1024]; 
    int len; 
    try { 
     while ((len = inputStream.read(buf)) != -1) { 
      outputStream.write(buf, 0, len); 
     } 
     outputStream.close(); 
     inputStream.close(); 
    } catch (IOException e) { 
     Log.e("IOException readTextFile", e.getMessage()); 
    } 
    return outputStream.toString(); 
} 

編輯:根據你的建議,我試過這種方法。它更好嗎?謝謝。

private void populateArray(){ 
    AssetManager assetManager = getAssets(); 
    InputStream inputStream = null; 
    Reader iStreamReader = null; 
    try { 
     inputStream = assetManager.open("List.txt"); 
     iStreamReader = new InputStreamReader(inputStream, "UTF-8"); 
    } catch (IOException e) { 
     Log.e("IOException populateArray", e.getMessage()); 
    } 
    String String = readTextFile(iStreamReader); 
    // more code here 
} 

private String readTextFile(InputStreamReader inputStreamReader) { 
    StringBuilder sb = new StringBuilder(); 
    char buf[] = new char[2048]; 
    int read; 
    try { 
     do { 
      read = inputStreamReader.read(buf, 0, buf.length); 
      if (read>0) { 
       sb.append(buf, 0, read); 
      } 
     } while (read>=0); 
    } catch (IOException e) { 
     Log.e("IOException readTextFile", e.getMessage()); 
    } 
    return sb.toString(); 
} 

回答

3

這個例子並不好。它充滿了不好的做法(隱藏異常,不關閉finally塊中的流,不指定明確的編碼等)。它使用1024字節長的緩衝區,因爲它沒有任何方式知道輸入流的長度。請參閱Java IO tutorial以瞭解如何從文件中讀取文本。

+0

沒錯。考慮一下:如果你的字節數組長度與輸入流的長度一樣長,並且文件的大小應該是4GB,那麼你將把所有4GB的文件加載到RAM中,從而減慢計算機的速度,可能導致系統崩潰。這就是爲什麼您一次讀取1024個字節的原因,以最大限度地減少陣列使用的內存量。 – OzzyTheGiant

1

您正在將文件讀取到1024字節的緩衝區中。 然後將這些1024個字節寫入outputStream。 重複此過程,直到將整個文件讀入outputStream。由於JB Nizet提到這個例子充滿了壞習慣。

0

要從文件中讀取我一般會使用掃描器和StringBuilder。

 Scanner scan = new Scanner(new BufferedInputStream(new FileInputStream(filename)), "UTF-8"); 
     StringBuilder sb = new StringBuilder(); 
     while (scan.hasNextLine()) { 
      sb.append(scan.nextLine()); 
      sb.append("\n"); 
     } 
     scan.close 

     return sb.toString(); 

試着拋出你的異常,而不是吞嚥它們。來電者必須知道您的文件有問題。

編輯:另請注意,使用BufferedInputStream非常重要。否則,它會嘗試按字節讀取字節,可能會很慢。

+0

這可能會將\ r \ n轉換爲\ n,破壞原始內容。 –

+0

@JB Nizet是的,你是對的。你知道一個更好的方法來實現這個嗎? – Lynch

+0

是的。將輸入流封裝在InputStreamReader中,並在此時指定字符集。啓動一個讀入char []緩衝區(例如1024或2048個字符)的循環,直到返回-1。在每次迭代時,將已讀入char buffer的內容追加到StringBuilder中,並返回StringBuilder的內容。 –

0

難道我不想將它初始化爲我的文本文件的長度嗎?另外,我不想使用char,而不是字節?

是的,是的......正如其他答案所說,你已經選擇了一個錯誤的例子。

但是,兩者都存在理論問題;即使用字符緩衝器而不是字節緩衝器將緩衝器長度設置爲文件長度。問題是文件大小是以字節爲單位進行測量的,但是緩衝區的大小需要用字符來衡量。這通常很好,但它理論上可能是,您將需要比以字節爲單位的文件大小更多的字符;例如如果輸入文件使用6位字符集並將4個字符打包爲3個字節。沒問題。

+0

我在JBNizet的鏈接上閱讀了關於字符流的部分,但似乎我無法使用FileWriter來讀取我的輸入流,因爲assetManager.open(「3500LineTextFile.txt」)返回的是字節流而不是charstream。那麼這是否意味着我不能使用字符? – b10hazard

+0

FileWriter用於將文本寫入文件。你想從輸入流中讀取字符。這是InputStreamReader的用途。 –

相關問題