31

Hey I'm trying to open a file and read just from an offset for a certain length! I read this topic: How to read a specific line using the specific line number from a file in Java? in there it said that it's not to possible read a certain line without reading the lines before, but I'm wondering about bytes!

FileReader location = new FileReader(file);
BufferedReader inputFile = new BufferedReader(location);
// Read from bytes 1000 to 2000
// Something like this
inputFile.read(1000,2000);

Is it possible to read certain bytes from a known offset?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Khashayar
  • 2,014
  • 3
  • 22
  • 31
  • 4
    Read up on [reading files using Java.](http://www.cs.usfca.edu/~parrt/course/601/lectures/io.html) `Seek` methods exist. – Robert Harvey Mar 12 '12 at 16:42
  • Did you manage to implement the suggested solutions? I'm trying to do the same, but having a really hard time. – kryzystof Mar 17 '21 at 08:38
  • Hi @kryzystof , Yes I managed this back then with RandomAccessFile class (the accepted answer). Unfortunately I don't have access to the code any more since its been 9 years – Khashayar Mar 17 '21 at 12:07

2 Answers2

24

RandomAccessFile exposes a function:

seek(long pos) 
          Sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs.
Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
  • Is this thing fast or it just go through the previous ones also? – Khashayar Mar 12 '12 at 16:44
  • I would imagine it is fast, since you are just referencing the pointer. IIRC a jump table of sorts is created and it should be O(1) time. – Woot4Moo Mar 12 '12 at 16:46
  • Technically it should jump directly, since the bytes of a single file are contiguous on disk. – Tudor Mar 12 '12 at 16:50
  • @Tudor I thought that there was no guarantee, granted the last time I read anything about how the system writes to the disk was about 3 years ago. – Woot4Moo Mar 12 '12 at 16:52
  • @Woot4Moo: Indeed, if the disk is heavily fragmented you may have files split in several places, but normally they should be contiguous. – Tudor Mar 12 '12 at 16:54
  • Yeah But My file is right i want and is not going to change so it work ok for me! – Khashayar Mar 12 '12 at 16:55
18

FileInputStream.getChannel().position(123)

This is another possibility in addition to RandomAccessFile:

File f = File.createTempFile("aaa", null);
byte[] out = new byte[]{0, 1, 2};

FileOutputStream o = new FileOutputStream(f);
o.write(out);
o.close();

FileInputStream i = new FileInputStream(f);
i.getChannel().position(1);
assert i.read() == out[1];
i.close();
f.delete();

This should be OK since the docs for FileInputStream#getChannel say that:

Changing the channel's position, either explicitly or by reading, will change this stream's file position.

I don't know how this method compares to RandomAccessFile however.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • 2
    This seems like a more flexible solution than the `RandomAccessFile`, because it allows you to return the `InputStream` to be processed outside of your method. In case of the RAF, if you wanted to do that, you would not be able to close the RAF, thus having a resource leak. Unless I misunderstood something. – PeterG Jun 13 '18 at 05:56