必要
ファイルポインタのバックトラックを実現するには、ファイル読み取りストリームを使用します。テキスト ファイル内のデータの各行を読み取り、最後に読み取った文字の位置と次に読み取る文字の位置を記録し、最後に読み取った行を出力します。
研究室環境
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() 関数が失敗することが記載されています。ファイルバイト入力ストリームオブジェクトを使用するには! !!
それを達成する方法については、次の記事を参照してください。