1

I need to read a section of a structured binary file by passing an index. However, DataInputStream does not support mark/reset. How can I achieve what I want? Are there any other classes that allow me to easily achieve this?

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();
    }
  }
}
user1040876
  • 31
  • 1
  • 3
  • 6

2 Answers2

3

It is not DataInputStream that doesn't support mark/reset. DataInputStream simply delegates the calls to mark/reset to the underlying stream (in this case a FileInputStream). The FileInputStream does however not support mark/reset operations (iirc). The solution to this problem is to first wrap the FileInputStream in a BufferedInputStream before passing it to the DataInputStream. That should make it possible to use the desired operations. Ie:

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

Also, I am not entirely sure, but from what I understand you might be using the argument for mark incorrectly. According to the JavaDoc the argument means:

the maximum limit of bytes that can be read before the mark position becomes invalid.

Thus, calling mark with the argument zero would not be particularly useful.

Jiddo
  • 1,256
  • 1
  • 10
  • 15
1

wrap in a BufferedInputStream it implements mark

btw your mark call should give the amount of bytes that you expect to be read until a reset will happen. if you read past that the mark becomes invalid and reset will throw

or use a RandomAccessFile

ratchet freak
  • 47,288
  • 5
  • 68
  • 106