Java でファイル ポインタのバックトラッキングを実装する

Java でファイル ポインタのバックトラッキングを実装する

必要

ファイルポインタのバックトラックを実現するには、ファイル読み取りストリームを使用します。テキスト ファイル内のデータの各行を読み取り、最後に読み取った文字の位置と次に読み取る文字の位置を記録し、最後に読み取った行を出力します。

研究室環境

JDK8、アイデア

実験手順

一連の考え

この実験では、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