Java中实现文件指针回溯

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()函数就会失效,至于怎么解决,应该可以使用文件字节输入流对象!!!
具体怎么实现,请参考我的下一篇文章!

猜你喜欢

转载自blog.csdn.net/dubulingbo/article/details/106996696