次のように 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());
}
いくつかのことに気付くでしょう:
- このバージョンは、InputStream を実装しているため、バイト数をカウントします。
- クライアント コードで自分で文字数またはバイト数をカウントする方が簡単な場合があります。
- このコードは、LineNumberReader によって処理されていなくても、ファイルシステムからバッファーに読み取られるとすぐにバイトをカウントします。これを回避するには、代わりに LineNumberReader のサブクラスに count 文字を入れることができます。残念ながら、バイト数とは異なり、ファイル内の文字数を簡単に知る方法がないため、パーセンテージを簡単に計算することはできません。