1

i'm want to code a method that reads part from files into byte-arrays. for this i'm using fileinputstream and a buffered inputstream.

like this:

fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);

I do this only once by calling a method name "OpenFile(String File)". Once the File has been opened with this method, i try to operate with the function: "ReadParts(byte[] buffer, int offset, int len)"

dis.read(buffer, offset, len);            
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

// used data:
// file = "C:\Temp\test.txt" with a size of 949
// buffer: always in this case with a size of 237, except for the last one its 238
// offsets: 0, 237, 474, 711 
// len is always 237, except for the last one its 238

the line dis.read() throws after the first step always a indexOutOfBounds errormessage but i can't figure it out why and what. using the netbeans debugger didnt helped, since i can't find the problem with the indices.....

Tony B
  • 344
  • 5
  • 19
  • Please post the code where you compute offset and len and where you initialize buffer. It is very likely this causes your problems. – AlexS Mar 14 '12 at 11:51

4 Answers4

2

If you read the Stream into an array of buffers your offset and len will always have to be:

offset = 0;
len = buffer.length();

These parameters specify where the data is put in the buffer and NOT which data is read from the Stream. The Stream is read continuus (or however this gets spelled?)!

If you always call:

buffer = new byte[256];
dis.read(buffer, 0, 256);

This will happen: Before the first call the Streamposition (position of the next byte that gets returned) is 0.

  1. Streamposition after call=256 and buffer contains the bytes 0-255
  2. Streamposition after call=512 and buffer contains the bytes 256-511
  3. ...

    dis.reset();

Streamposition is 0 once more.

This code reads only the bytes 256-511 from a Stream into a buffer:

byte[] buffer = new byte[512];
dis.skip(256);
dis.read(buffer, 0, 256);

See that the last 256 bytes of buffer aren't filled. This is one of the differences between read(byte[], int, int) and read(byte[])!

Here are some links for you which describe the concept of a stream and the usage of read-method: read() Streams

AlexS
  • 5,295
  • 3
  • 38
  • 54
  • so why then using the read(byte, off, len) function? read(byte[]) would do the same job -> offset = 0 and len = byte.length. which means it reads the whole file. My plan is to read parts from a file and not the whole file. again, i plan (in this example) to read from 237 to 474. this are 236 bytes . so it should be enough if the buffer is 237 long. i just dont get the connection between offset (which is >= 0) and offset + len (for the buffer size).... – Tony B Mar 14 '12 at 11:58
  • you use the read(byte, offset, len) if you want to place the read bytes in special places in the buffer. If you just want to read some and not all bytes from the stream you have to use skip(). If you use skip with absolute offsets in your stream you will have to call reset() as well, if something was read from this stream before. – AlexS Mar 14 '12 at 12:08
  • i just did this in order to skip the null-bytes: for (int i = 0; i < realBytes.length; i++) { realBytes[i] = buffer[i + offset]; } – Tony B Mar 14 '12 at 12:13
1

how are you coming up with offset and len. My guess right now is you offset + len is greater than the buffer.

nate_weldon
  • 2,289
  • 1
  • 26
  • 32
  • well, is here a problem that i don't understand right now? regarding the docs: dis.read(b, off, len): b - the buffer into which the data is read. off - the start offset of the data. len - the maximum number of bytes read. so i have to alter the buffer in order to get the bytes 238 to 474? (in which case 237 is 1 more than enough?!) – Tony B Mar 14 '12 at 11:43
1

You will get IndexOutOfBoundsException - If

  • offset is negative,

  • len is negative,

  • len is greater than buffer.length - off

Example for point 3:

If there are 500 characters or 1500 characters in the input file, the following program will run successfully,

byte[] buffer = new byte[1000];
int offset = 0;
int len = 1000;
dis.read(buffer, offset, len);            
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

But it will fail and throw exception if,

byte[] buffer = new byte[1000];
int offset = 0;
int len = 1001;
dis.read(buffer, offset, len); 
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

Check the value of length in both the cases.

Anantha Krishnan
  • 3,068
  • 3
  • 27
  • 37
  • yeah, but that would mean that i need a bigger buffer if i want to read from byte 237 to 474, even the "real" byte-size is 236?? – Tony B Mar 14 '12 at 11:50
0

The offset is the offset in the buffer not the file.

I suspect what you want is

byte[] buffer = new byte[237];

int len = dis.read(buffer); // read another 237 bytes.

if (len < 0) throw new EOFException(); // no more data.
for(int i = 0; i < len; i++)
   System.out.print((char)buffer[i]);
// or
System.out.print(new String(buffer, 0, 0, len));

In your debugger, can you check that offset >= 0 and offset + lengh <= buffer.length?

From InputStream.read()

public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
    throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
    throw new IndexOutOfBoundsException();

One of the conditions checked for is invalid.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • offset is 237, and len is 237, too. so the bufferlengh is 237. doesn't it count at the offsetnum with a len from 237?? the exception contains no detail, or i cant extract the detail... :/ (when i use ex.getCause() i'll get a nullpointerexception) – Tony B Mar 14 '12 at 11:37
  • say so, i have to raise the buffer, even if i only want to read 237 bytes (237 to 474 from the file) needs in the 2nd step a doubled buffer? right? – Tony B Mar 14 '12 at 11:47
  • No, see my post. You are misusing offset and len. – AlexS Mar 14 '12 at 11:55
  • @TonyB if you are reading 237 (length) bytes from position 237 (offset) the buffer (byte b[]) needs to be at least 474 byte long. – Peter Lawrey Mar 14 '12 at 11:57
  • @AlexS: your post is somehow not that what i asked for, your example is only there if i want to start from 0 to the length of the buffer. Peter Lawrey got it right....somehow (in my point of view) its a bit unlogical since the buffer would be longer then the bytes read.. but okay i'll give it a try. thanks peter. – Tony B Mar 14 '12 at 12:02
  • okay, worked. but now i have 237 "NULL" in the document, which isn't intended. somehow the behaviour of this bufferreader is shit :) – Tony B Mar 14 '12 at 12:08
  • Do you mean BufferedInputStream, rather than BufferedReader? Are you sure you are writing only the bytes you read() i.e. `int len = dis.read(buffer);` – Peter Lawrey Mar 14 '12 at 12:25