簡體   English   中英

Java - 從文件中讀取。輸入流與讀者

[英]Java — reading from a file. Input stream vs. reader

在我看到的從文件中讀取的每個Java實現中,我幾乎總是看到用於逐行讀取的文件讀取器。 我的想法是,這將是非常低效的,因為它需要每行系統調用。

我一直在做的是使用輸入流並直接獲取字節。 在我的實驗中,這明顯更快。 我的測試是一個1MB的文件。

    //Stream method
    try {
        Long startTime = new Date().getTime();

        InputStream is = new FileInputStream("test");
        byte[] b = new byte[is.available()];
        is.read(b);
        String text = new String(b);
        //System.out.println(text);

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

    //Reader method
    try {
        Long startTime = new Date().getTime();

        BufferedReader br = new BufferedReader(new FileReader("test"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        String text = sb.toString();

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

這給出了以下結果:

Text length: 1054631, Total time: 9
Text length: 1034099, Total time: 22

那么,為什么人們使用讀者而不是流?

如果我有一個方法接受一個文本文件並返回一個包含所有文本的字符串,那么使用流做它是否更好?

你正在比較蘋果和香蕉。 即使使用bufferedReader,一次讀取一行也會降低效率,而不是盡可能快地抓取數據。 請注意,不鼓勵使用可用,因為它在所有情況下都不准確。 當我開始使用密碼流時,我發現了這一點。

FileReader通常與BufferedReader一起使用,因為通常逐行讀取文件是有意義的,特別是如果文件具有明確定義的記錄結構,其中每個記錄對應一行。

此外, FileReader可以簡化處理字符編碼和轉換的一些工作,如javadoc中所述:

用於讀取字符文件的便捷類。 此類的構造函數假定默認字符編碼和默認字節緩沖區大小是合適的... FileReader用於讀取字符流。

嘗試增加BufferedReader緩沖區大小。 例如:

BufferedReader br = new BufferedReader(new FileReader("test"),2000000);

如果選擇合適的緩沖區大小,則速度會更快。

然后在使用Reader的示例中,您將花時間填充StringBuilder。 如果需要處理行,則必須逐行讀取文件。 但是,如果您只需要讀取字符串中的文本,則使用public int read(char[] cbuf)讀取更大的文本塊,並將塊寫入使用適當大小初始化的StringWriter

選擇使用InputStreamReader不依賴於性能。 通常,在閱讀文本數據時使用Reader ,因為使用閱讀器可以更輕松地處理字符集。

還有一點,你的代碼在這里

byte[] b = new byte[is.available()];
is.read(b);
String text = new String(b);

這是不正確的。 文檔說明

請注意,雖然InputStream的某些實現將返回流中的總字節數,但許多實現不會。 使用此方法的返回值來分配用於保存此流中所有數據的緩沖區絕對不正確。

所以要注意,你需要解決它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM