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

全部评论

相关推荐

面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务