2

JavaにはLineNumberReader、現在の行を追跡できる機能がありますが、ストリーム内のバイト(または文字)の位置を追跡するにはどうすればよいですか?

lseek(<fd>,0,SEEK_CUR)Cのファイルに似たものが欲しいです。

編集:私はを使用してファイルを読んでいて、LineNumberReader in = new LineNumberReader(new FileReader(file))「ファイルのXX%を処理した」のようなものを時々印刷できるようにしたいと思っています。私が知っている最も簡単な方法は、file.length()最初のものを見て、現在のファイル位置をそれで割ることです。

4

2 に答える 2

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 のサブクラスに count 文字を入れることができます。残念ながら、バイト数とは異なり、ファイル内の文字数を簡単に知る方法がないため、パーセンテージを簡単に計算することはできません。
于 2012-06-18T01:45:28.493 に答える