2010-10-07 101 views
2

我試圖用Java輸出文本文件到控制檯。我想知道什麼是最有效的方式?Java:輸出文本文件到控制檯

但是,我研究了幾種方法,很難區分哪些是性能最差的解決方案。

將文本文件輸出到控制檯將涉及讀取文件中的每一行,然後將其寫入控制檯。

是它更好地使用:

  1. 緩衝讀卡器,一個FileReader及讀取行,做了一堆的System.out.println調用的?

    BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\")); 
    while (in.readLine() != null) { 
         System.out.println(blah blah blah);   
    }   
    in.close(); 
    
  2. 掃描儀讀取文件中的每一行並執行system.print調用?

    while (scanner.hasNextLine()) { 
        System.out.println(blah blah blah); 
    } 
    

感謝。

回答

3

如果您對文本文件包含的基於字符的數據不感興趣,只需將其作爲字節「原始」進行流式傳輸即可。

InputStream input = new BufferedInputStream(new FileInputStream("C:/logs.txt")); 
byte[] buffer = new byte[8192]; 

try { 
    for (int length = 0; (length = input.read(buffer)) != -1;) { 
     System.out.write(buffer, 0, length); 
    } 
} finally { 
    input.close(); 
} 

這可以節省字節和字符之間不必要的按摩成本,還可以在換行符上掃描和分割並再次附加它們。

至於表現,你會發現this article有趣。根據文章,FileChannel與一個256K字節數組通過包裝ByteBuffer讀取並直接從字節數組寫入是最快的方法。

FileInputStream input = new FileInputStream("C:/logs.txt"); 
FileChannel channel = input.getChannel(); 
byte[] buffer = new byte[256 * 1024]; 
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); 

try { 
    for (int length = 0; (length = channel.read(byteBuffer)) != -1;) { 
     System.out.write(buffer, 0, length); 
     byteBuffer.clear(); 
    } 
} finally { 
    input.close(); 
} 
+0

有趣的文章。這正是我期待的,謝謝! :) – user459811 2010-10-08 00:08:57

+0

如果文件和輸出目標使用不同的字符編碼,傳輸原始腳本將產生奇怪的結果(似乎中斷)。 – Raedwald 2016-02-10 13:43:53

+0

@Rededwald:沒錯。這只是服務器的錯誤(假設頭部是正確的),但客戶端的錯誤,所以通常更容易修復。 – BalusC 2016-02-10 13:47:54

-1

爲什麼你不嘗試它們並測量它們?另外,爲什麼你需要在Java中做到這一點? Windows和Linux都有命令來執行此操作。 (用於Windows的'type',用於Linux的'cat')

+0

我假設它是一個更大的程序的一部分,但如果它不是,那麼我支持這個答案。 :) – Catchwa 2010-10-07 22:21:59

+0

儘管如此,OP可以將這兩位代碼鍵入到IDE中,並將它們鍵入到Web瀏覽器中,並且現在有一個與其硬件相關的答案。 – dty 2010-10-07 22:26:29

+0

我知道貓和類型。我之所以問,是因爲我也希望替代掃描儀和緩衝讀取器。 – user459811 2010-10-07 22:31:28

3

如果您只想將一個文件的內容(並且不想打印下一個int/double/etc)打印到控制檯那麼一個BufferedReader是好的。

儘管如此,您的代碼不會產生您所追求的結果。試試這個:

BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\log001.txt")); 
String line = in.readLine(); 
while(line != null) 
{ 
    System.out.println(line); 
    line = in.readLine(); 
} 
in.close(); 

我不會太掛了一下,雖然,因爲它更可能是主要瓶頸將是你的控制檯打印Java已發送它的信息的能力。

+0

你應該在路徑名中使用斜線('/')。 Java會將其轉換爲操作系統特定的分隔符。 – 2010-10-07 23:36:42

2

如果你想要的是最有效的,沒有處理之間轉儲文件的內容到控制檯,將數據轉換成字符和尋找換行是不必要的開銷。相反,你可以從文件中讀取的字節塊,然後直接寫出來System.out

package toconsole; 

import java.io.BufferedInputStream; 
import java.io.FileInputStream; 

public class Main { 
    public static void main(String[] args) { 
     BufferedInputStream bis = null; 
     byte[] buffer = new byte[8192]; 
     int bytesRead = 0; 
     try { 
      bis = new BufferedInputStream(new FileInputStream(args[0])); 
      while ((bytesRead = bis.read(buffer)) != -1) { 
       System.out.write(buffer, /* start */ 0, /* length */ bytesRead); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { bis.close(); } catch (Exception e) { /* meh */ } 
     } 
    } 
} 

如果您有沒有碰到過這樣的成語在while條件來之前,語句都分配將bis.read的結果寫入bytesRead,然後將其與-1進行比較。所以我們繼續讀取字節到緩衝區,直到我們被告知我們在文件的末尾。我們在System.out中使用bytesRead。編寫以確保我們只寫入剛剛讀取的字節,因爲我們不能假定所有文件都是8 kB的倍數!