web-dev-qa-db-ja.com

java rewind()/ reset()機能によるファイル入力

大きなファイルを2つのパスで読み取るために、ある種の入力ストリーム(たとえば、InputStreamまたはFileChannel)を取り込む関数を作成する必要があります。1つは容量を事前計算するため、もう1つは「実際の」作業を行うためです。ファイル全体を一度にメモリにロードしたくない(サ​​イズが小さい場合を除く)。

適切なJavaこの機能を提供するクラス? FileInputStream自体はmark()/ reset()をサポートしていません。BufferedInputStreamはサポートしていると思いますが、これを行うためにファイル全体を保存する必要があるかどうかは不明です。

Cはとてもシンプルなので、fseek()、ftell()、rewind()を使用するだけです。 :-(

33
Jason S

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);
    }
}
25
ykaganovich

BufferedInputStreamは、コンテンツをメモリにバッファリングすることにより、markをサポートします。予測可能なサイズの比較的小さな先読みのために予約するのが最適です。

代わりに、RandomAccessFileを直接使用するか、rewind()メソッドで拡張された具体的なInputStreamの基礎として使用できます。

または、パスごとに新しいFileInputStreamを開くことができます。

22
erickson

関連するFileChannelFileInputStreamから取得した場合、positionメソッドを使用して、ファイルポインターをファイル内の任意の場所に設定できます。

FileInputStream fis = new FileInputStream("/etc/hosts");
FileChannel     fc = fis.getChannel();


fc.position(100);// set the file pointer to byte position 100;
19
SW-Eng

_Java.nio.channels.FileChannel_には、Cのfseek()のように位置をゼロにリセットするメソッドposition(long)があります。

7
Arne Burmeister

RandomAccessFile はあなたが望むものです:

6
dfa

巻き戻し可能な文字数がわかっている限り、PushbackInputStreamも機能します。

2
CT Arrington

Java.io.RandomAccessFileを確認してください。

2
Rich Seller

あなたが望むのはRandomAccessFileInputStreamです-マーク/リセットでInputStreamインターフェースを実装し、時にはRandomAccessFilesに基づいてシークします。必要なことを実行する可能性のある実装がいくつかあります。

ソースの完全な1つの例は http://www.fuin.org/utils4j/index.html にありますが、インターネットを検索する他の多くの人が見つかり、どれも正確に一致しない場合はコーディングが簡単です。

2
user1857918

BufferedInputStreamにはmark(readlimit)reset()があります。マークを有効にするには、readlimitfilesizeより大きくする必要があります。 file.length()+1は問題ありません。つまり、マークはreadlimitバイトが読み取られるまで有効であるため、reset()で戻ることができます。

2
Byung Ahn