2012-06-17 46 views
1

Java有LineNumberReader它讓我跟蹤我所在的線路,但是如何跟蹤流中的字節(或字符)位置?如何找出從流中讀取了多少個字符或字節?

我想下的文件類似於lseek(<fd>,0,SEEK_CUR)東西

編輯: 我讀使用LineNumberReader in = new LineNumberReader(new FileReader(file))一個文件,我希望能夠打印類似「文件處理XX%」每一個現在,然後。我知道的最簡單的方法是先看file.length(),然後用當前文件位置除以它。

+0

你試圖使用什麼類型的流?文件流是一個實時通信。流等...? – trumpetlicks

+0

我無法想象爲什麼你會想知道,也不知道你如何才能真正弄清楚。事實上,這是一個流,因爲你不斷接受更多的事情,所以不可能有位置。你可以做的最多的是記錄你自從通過一個簡單的整數建立流並讀取它後讀取了多少字節。也許如果你給我們更多關於你的意圖的細節...... –

+0

你可以看看[RandomAccessFile](http://docs.oracle.com/javase/1.4.2/docs/api/java/io/RandomAccessFile。 HTML),但我不知道它是否適合你正在看的流。 – Thomas

回答

1

我建議延長FilterInputStream中的如下

public class ByteCountingInputStream extends FilterInputStream { 

    private long position = 0; 

    protected ByteCountingInputStream(InputStream in) { 
     super(in); 
    } 

    public long getPosition() { 
     return position; 
    } 

    @Override 
    public int read() throws IOException { 
     int byteRead = super.read(); 
     if (byteRead > 0) { 
      position++; 
     } 
     return byteRead; 
    } 

    @Override 
    public int read(byte[] b) throws IOException { 
     int bytesRead = super.read(b); 
     if (bytesRead > 0) { 
      position += bytesRead; 
     } 
     return bytesRead; 
    } 

    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
     int bytesRead = super.read(b, off, len); 
     if (bytesRead > 0) { 
      position += bytesRead; 
     } 
     return bytesRead; 
    } 

    @Override 
    public long skip(long n) throws IOException { 
     long skipped; 
     skipped = super.skip(n); 
     position += skipped; 
     return skipped; 
    } 

    @Override 
    public synchronized void mark(int readlimit) { 
     return; 
    } 

    @Override 
    public synchronized void reset() throws IOException { 
     return; 
    } 

    @Override 
    public boolean markSupported() { 
     return false; 
    } 

} 

而且你會使用這樣的:

File f = new File("filename.txt"); 
ByteCountingInputStream bcis = new ByteCountingInputStream(new FileInputStream(f)); 
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(bcis)); 
int chars = 0; 
String line; 
while ((line = lnr.readLine()) != null) { 
    chars += line.length() + 2; 
    System.out.println("Chars read: " + chars); 
    System.out.println("Bytes read: " + bcis.getPosition()); 
} 

你會發現幾件事情:

  1. 這個版本計數,因爲字節它實現了InputStream。
  2. 在客戶端代碼中對自己的字符或字節進行計數可能會更容易。
  3. 即使這些代碼還沒有被LineNumberReader處理過,它們也會在從文件系統讀入緩衝區時立即計算字節數。您可以將計數字符放在LineNumberReader的子類中,而不是爲了解決此問題。不幸的是,你不能容易地產生一個百分比,因爲與字節不同,沒有廉價的方法來知道文件中的字符數。
+1

我相信Apache Commons IO有一個計數輸入流裝飾器。 http://commons.apache.org/io/api-1.4/org/apache/commons/io/input/CountingInputStream.html –

相關問題