大きなファイルを2つのパスで読み取るために、ある種の入力ストリーム(たとえば、InputStreamまたはFileChannel)を取り込む関数を作成する必要があります。1つは容量を事前計算するため、もう1つは「実際の」作業を行うためです。ファイル全体を一度にメモリにロードしたくない(サイズが小さい場合を除く)。
適切なJavaこの機能を提供するクラス? FileInputStream自体はmark()/ reset()をサポートしていません。BufferedInputStreamはサポートしていると思いますが、これを行うためにファイル全体を保存する必要があるかどうかは不明です。
Cはとてもシンプルなので、fseek()、ftell()、rewind()を使用するだけです。 :-(
FileChannelを参照する答えは適切だと思います。
この機能をカプセル化する入力ストリームの実装例を次に示します。委任を使用するため、本当のFileInputStreamではありませんが、通常は十分なInputStreamです。要件がある場合は、同様にFileInputStreamを拡張できます。
テストされていません、自己責任で使用してください:)
public class MarkableFileInputStream extends FilterInputStream {
private FileChannel myFileChannel;
private long mark = -1;
public MarkableFileInputStream(FileInputStream fis) {
super(fis);
myFileChannel = fis.getChannel();
}
@Override
public boolean markSupported() {
return true;
}
@Override
public synchronized void mark(int readlimit) {
try {
mark = myFileChannel.position();
} catch (IOException ex) {
mark = -1;
}
}
@Override
public synchronized void reset() throws IOException {
if (mark == -1) {
throw new IOException("not marked");
}
myFileChannel.position(mark);
}
}
BufferedInputStream
は、コンテンツをメモリにバッファリングすることにより、mark
をサポートします。予測可能なサイズの比較的小さな先読みのために予約するのが最適です。
代わりに、RandomAccessFile
を直接使用するか、rewind()
メソッドで拡張された具体的なInputStream
の基礎として使用できます。
または、パスごとに新しいFileInputStream
を開くことができます。
関連するFileChannel
をFileInputStream
から取得した場合、positionメソッドを使用して、ファイルポインターをファイル内の任意の場所に設定できます。
FileInputStream fis = new FileInputStream("/etc/hosts");
FileChannel fc = fis.getChannel();
fc.position(100);// set the file pointer to byte position 100;
_Java.nio.channels.FileChannel
_には、Cのfseek()のように位置をゼロにリセットするメソッドposition(long)
があります。
RandomAccessFile はあなたが望むものです:
巻き戻し可能な文字数がわかっている限り、PushbackInputStreamも機能します。
Java.io.RandomAccessFileを確認してください。
あなたが望むのはRandomAccessFileInputStream
です-マーク/リセットでInputStream
インターフェースを実装し、時にはRandomAccessFiles
に基づいてシークします。必要なことを実行する可能性のある実装がいくつかあります。
ソースの完全な1つの例は http://www.fuin.org/utils4j/index.html にありますが、インターネットを検索する他の多くの人が見つかり、どれも正確に一致しない場合はコーディングが簡単です。
BufferedInputStream
にはmark(readlimit)
とreset()
があります。マークを有効にするには、readlimit
をfilesize
より大きくする必要があります。 file.length()+1
は問題ありません。つまり、マークはreadlimit
バイトが読み取られるまで有効であるため、reset()
で戻ることができます。