Java有LineNumberReader
,它让我可以跟踪我所在的行,但是如何跟踪流中的字节(或字符)位置?
我希望C中的文件与lseek(<fd>,0,SEEK_CUR)
类似。
编辑:
我正在使用LineNumberReader in = new LineNumberReader(new FileReader(file))
阅读文件,我希望能够偶尔打印“处理文件的XX%”之类的内容。我知道最简单的方法是首先查看file.length()
并按其划分当前文件位置。
答案 0 :(得分: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 :(得分:1)
ByteCountingInputStream 解决方案的缺点是,即使在 LineNumberReader 处理之前,它也会对输入字节进行计数。这不是我报告所需要的,我想出了一个替代方案。我假设输入文件是带有Unix样式行结尾的ASCII文本(单个 LF 字符)。
我已经构建了 LineNumberReader 的子集,可以添加位置报告:
import java.io.*;
public class FileLineNumberReader {
private final LineNumberReader lnr;
private final long length;
private long pos;
public FileLineNumberReader(String path) throws IOException {
lnr = new LineNumberReader(new FileReader(path));
length = new File(path).length();
}
public long getLineNumber() {
return lnr.getLineNumber();
}
public String readLine() throws IOException {
String res = lnr.readLine();
if (res != null) {
pos += res.length() + 1;
}
return res;
}
public long getPercent() {
return 100*pos/length;
}
}
请注意,此类隐藏了为封装的 LineNumberReader 定义的许多方法,这些方法与我的目的无关。