Some quirks in InputStream.read() ?

D

DaLoverhino

Hello. I have a FileInputStream, and I try to do the following:

//Save the file's content into a String
while( (readcount = in.read( buffer, 0, buffer.length) != -1) {
// Add buffer to an ever growing string.
}

Now, what I'm noticing is that my buffer.length == 256, and the
tail end of the file is not being loaded into the string.

So what it appears like is happening is that I ask for 256 bytes,
the FileInputStream can only give me say 18 bytes, so it then
returns a -1.

I was expecting in.read(...) to return 18, then on the next call
return -1.

I went on the sun site and found out there's nothing addressing this
specific situation. So does that mean, if I change compilers/machines,
this code could 'do the right thing'?

Does it mean, I have to use available() in order to ensure proper
behavior
across all platforms (that is hardware, compiler, JVM.)? It would seem
against the spirit of Java if it the above code does different things
on
different platforms? I must be missing something here.
thanks for your time.
 
G

Gordon Beaton

Hello. I have a FileInputStream, and I try to do the following:

//Save the file's content into a String
while( (readcount = in.read( buffer, 0, buffer.length) != -1) {
// Add buffer to an ever growing string.
}

Now, what I'm noticing is that my buffer.length == 256, and the
tail end of the file is not being loaded into the string.

So what it appears like is happening is that I ask for 256 bytes,
the FileInputStream can only give me say 18 bytes, so it then
returns a -1.

I was expecting in.read(...) to return 18, then on the next call
return -1.

That's what it should do. Post your real code, most likely that's
where the error is.
Does it mean, I have to use available() in order to ensure proper
behavior across all platforms (that is hardware, compiler, JVM.)?

In general, avoid the use of available(). At the very least, it will
make it difficult for you to detect EOF.

/gordon
 
C

Christian Schlichtherle

Indeed it should return 18 bytes first and then -1.

Another aspect: If you're really reading from a file (especially a large
one), you should use a buffer which is significantly larger than 256 - the
performance is way too poor otherwise because you make the system busy doing
I/O.

E.g. I have written a file synchronisation tool and did some performance
tests writing flash memory (1GB UltraII SD-Card) on Windows. Developing
software since 1988 I was a little bit conservative about buffer memory and
started with 512 bytes. It turned out that my application required an hour
run time to write about 62 MB to the flash memory while the Explorer
required less than a minute!

I then ran a lot of tests with differing buffer sizes and it turned out that
the optimum buffer size is 2MB (2*1024*1024)! With this buffer there was
finally no difference to the Explorer's performance.

Of course, if you use such a big buffer you should make sure it's reused
whenever possible and freed for the garbage collection asap. You will be
wasting a lot of memory otherwise...

Regards,
Christian
 
D

DaLoverhino

Yeah. You are right. I found my error, in five minutes
after I posted to this usenet! Ugh, makes me feel
retarded. Hey, thanks anyways.

The problem was in the buffer. I'm so use to a
nul char from my C days, that what I was seeing
on my display was the entire file, plus the remaining
'junk' in my buffer which wasn't the end of the file.


Anyways, the question still remains, I guess.
The sun site doesn't state that it should return
18 (less than buffer size), then -1. Or is this
implied from the text? I mean I think it's implied
in the text, but, I don't know....

Thanks everybody.
 
G

Gordon Beaton

Anyways, the question still remains, I guess.
The sun site doesn't state that it should return
18 (less than buffer size), then -1. Or is this
implied from the text? I mean I think it's implied
in the text, but, I don't know....

I think the text is quite clear.

From FileInputStream.read():

Returns the total number of bytes read into the buffer, or -1 if
there is no more data because the end of the file has been reached.

Obviously you haven't reached EOF yet if there are 18 bytes remaining.

InputStreams would be pretty useless if you immediately reached EOF
simply because you didn't know how much data was remaining.

/gordon
 
R

Rogan Dawes

DaLoverhino said:
Yeah. You are right. I found my error, in five minutes
after I posted to this usenet! Ugh, makes me feel
retarded. Hey, thanks anyways.

The problem was in the buffer. I'm so use to a
nul char from my C days, that what I was seeing
on my display was the entire file, plus the remaining
'junk' in my buffer which wasn't the end of the file.


Anyways, the question still remains, I guess.
The sun site doesn't state that it should return
18 (less than buffer size), then -1. Or is this
implied from the text? I mean I think it's implied
in the text, but, I don't know....

Thanks everybody.

Sounds to me like you are not copying the right amount of data from your
buffer into your output file.

The "correct" idiom is something like:

InputStream is;
byte[] buff = new byte[BUFFSIZE];
int got;
while ((got = is.read(buff)) > -1) {
// do something with buff[0..got]
// e.g. os.write(buff, 0, got);
// NOT os.write(buff);
// OR os.write(buff, 0, buff.length);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top