Java中实现文件指针回溯
需求
使用文件读取流实现文件指针的回溯。读取文本文件里的每一行数据,记录上一次读取字符的位置下一个即将读取字符的位置,并且输出最近读取的一行。
实验环境
Jdk8,IDEA
实验过程
思路
本实验使用了BufferReader中的remark、reset和readline函数:
1.remark() : 标记字符位置,若从未标记则默认标记文件第一个字符的位置
/** * Marks the present position in the stream. Subsequent calls to reset() * will attempt to reposition the stream to this point. * * @param readAheadLimit Limit on the number of characters that may be * read while still preserving the mark. An attempt * to reset the stream after reading characters * up to this limit or beyond may fail. * A limit value larger than the size of the input * buffer will cause a new buffer to be allocated * whose size is no smaller than limit. * Therefore large values should be used with care. * * @exception IllegalArgumentException If {@code readAheadLimit < 0} * @exception IOException If an I/O error occurs */
public void mark(int readAheadLimit) throws IOException {
if (readAheadLimit < 0) {
throw new IllegalArgumentException("Read-ahead limit < 0");
}
synchronized (lock) {
ensureOpen();
this.readAheadLimit = readAheadLimit;
markedChar = nextChar;
markedSkipLF = skipLF;
}
}
2.reset() : 回到最近一次标记的位置
/** * Resets the stream to the most recent mark. * * @exception IOException If the stream has never been marked, * or if the mark has been invalidated */
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
if (markedChar < 0)
throw new IOException((markedChar == INVALIDATED)
? "Mark invalid"
: "Stream not marked");
nextChar = markedChar;
skipLF = markedSkipLF;
}
}
3.readline() : 读取一行数据(从文件指针所在位置)
源码
public static void readTxtFile3(String fileName) throws IOException {
int past_pos = 1; // 文件指针上一次所在位置
int cur_pos = 1; // 文件指针当前所在位置(就是下一个要读取的字符的位置)
int cur_lineNumber = 1;
InputStreamReader fr = new InputStreamReader(new FileInputStream(fileName), "UTF-8"); // 指定以UTF-8编码读入
BufferedReader br = new BufferedReader(fr);
String line = "";
while ((line = br.readLine()) != null) {
// 文件未到文件尾
past_pos = cur_pos;
cur_pos += line.length();
br.mark(past_pos);
br.reset();
System.out.println("第 " + cur_lineNumber + " 行: " + past_pos + "," + cur_pos);
System.out.println(line);
cur_lineNumber++;
}
}
public static void main(String[] args) throws IOException {
String fileName = "D:\\data\\pdata\\all_person_info.txt"; // 读取文件
int totalNo = getTotalLines(fileName); // 获取文件的内容的总行数
System.out.println("本文总共有:" + totalNo + "行");
ReadFile2.readTxtFile3(fileName);
}
运行结果
不足
这几个函数的官方文档也提到过,如果文件过大,即字符数量超过int类型的表示范围,remark()函数就会失效,至于怎么解决,应该可以使用文件字节输入流对象!!!
具体怎么实现,请参考我的下一篇文章!