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。这应该可以使用所需的操作。IE:

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

另外,我不完全确定,但据我了解,您可能错误地使用了 mark 的参数。根据 JavaDoc,参数意味着:

在标记位置无效之前可以读取的最大字节数。

因此,使用参数 0 调用 mark 不会特别有用。

于 2011-11-11T20:09:44.670 回答
1

包装在一个 BufferedInputStream 它实现标记

顺便说一句,您的标记调用应该给出您希望在重置发生之前读取的字节数。如果您阅读过去该标记变为无效并且重置将抛出

或使用RandomAccessFile

于 2011-11-11T20:06:10.910 回答