2013-05-01 409 views
0

我有一個函數,在該函數中只給出一個BufferedInputStream,並且沒有關於要讀取的文件的其他信息。不幸的是,我不能改變方法定義,因爲它被我無法訪問的代碼調用。我一直在使用下面的代碼來讀取文件並將其內容的字符串:Java文件使用BufferedInputStream讀取大文件時截斷的IO

public String[] doImport(BufferedInputStream stream) throws IOException, PersistenceException { 
    int bytesAvail = stream.available(); 
    byte[] bytesRead = new byte[bytesAvail]; 
    stream.read(bytesRead); 
    stream.close(); 
    String fileContents = new String(bytesRead); 
    //more code here working with fileContents 
} 

我的問題是,對於大文件(> 2GB),該代碼會導致程序運行要麼極爲緩慢或截斷數據,取決於程序在其上執行的計算機。有沒有人有關於如何在這種情況下處理大文件的建議?

回答

1

你假設available()返回文件的大小;它不是。它返回可讀取的字節數,可能是小於或等於文件大小的任何數字。

不幸的是,在沒有其他關於文件數據長度的其他信息來源(即通過調用java.io.File.length())的情況下,沒有辦法只做一次就做什麼。相反,你必須從多次讀取中累積。一種方法是使用ByteArrayOutputStream。讀入固定的有限大小的陣列,然後將讀取的數據寫入ByteArrayOutputStream。最後,將字節數組拉出。您需要使用read()write()這三個參數形式,並查看read()的返回值,以便您確切知道每次調用時讀入緩衝區的字節數。

0

我不確定爲什麼你不認爲你可以一行一行讀取它。 BufferedInputStream只描述了底層流如何被訪問,它並沒有對你最終如何從中讀取數據施加任何限制。您可以像使用其他InputStream一樣使用它。

也就是說,讀它行由行,你可以做

InputStreamReader streamReader = new InputStreamReader(stream); 
BufferedInputReader lineReader = new BufferedInputReader(streamReader); 
String line = lineReader.readLine(); 
... 

[編輯]這種反應的問題,其中特別要求的方式來讀取輸入文件中的行內的原有字句逐線。

+0

*我*「不確定你爲什麼認爲」每個文件都有行。他們不。也很難理解爲什麼你認爲每個文件都有字符。他們不。從一個文件中讀取一行,可能有或沒有一個或多個文件,並不能解決實際問題。 -1。 – EJP 2013-05-01 10:15:08

+0

原始問題已修改。最初,海報表明他們傾向於逐行讀取文件,因此我假設輸入是帶有換行符的字符流。 http://stackoverflow.com/posts/16311485/revisions – Jacob 2013-05-01 15:14:13