1

インデックスを渡して構造化バイナリ ファイルのセクションを読み取る必要があります。ただし、DataInputStream はマーク/リセットをサポートしていません。どうすれば私が望むものを達成できますか? これを簡単に達成できる他のクラスはありますか?

import java.io.*;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;

class Test {
  public static int getInt(DataInputStream stream, int index) throws IOException {
    int offset = index * 4; // size of int
    stream.reset();
    stream.skip(offset);
    return stream.readInt();
  }

  public static void main(String[] args) {
    String filename = "test.data";
    try {
      DataOutputStream ostream = new DataOutputStream(new FileOutputStream(filename));
      for (int i=0; i<10; i++) {
        ostream.writeInt(i);
      }
      ostream.close();

      DataInputStream istream = new DataInputStream(new FileInputStream(filename));
      istream.mark(0);
      int i0 = getInt(istream, 0);
      int i3 = getInt(istream, 3);
      int i5 = getInt(istream, 5);
      System.out.printf("i0 = %d, i3 = %d, i5 = %d\n", i0, i3, i5);
      istream.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
4

2 に答える 2

3

マーク/リセットをサポートしていないのは DataInputStream ではありません。DataInputStream は、マーク/リセットの呼び出しを基になるストリーム (この場合は FileInputStream) に委任するだけです。ただし、FileInputStream は、マーク/リセット操作 (iirc) をサポートしていません。この問題の解決策は、最初に FileInputStream を BufferedInputStream でラップしてから DataInputStream に渡すことです。これにより、目的の操作を使用できるようになります。すなわち:

DataInputStream istream = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));

また、完全にはわかりませんが、私が理解していることから、マークの引数を間違って使用している可能性があります。JavaDoc によると、引数の意味は次のとおりです。

マーク位置が無効になる前に読み取ることができるバイトの最大制限。

したがって、引数ゼロを指定して mark を呼び出すことは特に有用ではありません。

于 2011-11-11T20:09:44.670 に答える
1

mark を実装する BufferedInputStream にラップする

ところで、マーク呼び出しは、リセットが発生するまで読み取られると予想されるバイト数を与える必要があります。マークが無効になり、リセットがスローされることを過去に読んだ場合

またはRandomAccessFileを使用します

于 2011-11-11T20:06:10.910 に答える