Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java read / write construction

Can someone explain me why this construction wont work:

while (fileInputStream.available()>0) {    
    fileOutputStream.write(fileInputStream.read());
}

and this one works just fine:

while (fileInputStream.available()>0) {
    int data = fileInputStream.read();
    fileOutputStream.write(data);
}

As for me they are identical, but 1st one wont write data correctly (will write half of file lenght / data).

like image 941
Hikaru Avatar asked Oct 06 '15 12:10

Hikaru


2 Answers

You are using the available() method incorrectly. The method is used to determine how many bytes are available to be read without blocking the thread.

Good Stack Overflow Question about available()

JavaDoc on available()


The correct way to check if you have reached the EOF is to see if the read() method returned -1:

int data = fileInputStream.read();
while (data != -1) {
    fileOutputStream.write(data);
    data = fileInputStream.read();
}

This method is probably going to be quite slow if you try to read in larger amounts of data. You can speed this up by reading in more bytes using the read(byte[] b, int off, int len) method. The loop will look quite similar to the other one.

byte [] buffer = new byte[1024]; // 1kb buffer
int numBytesRead = fileInputStream.read(buffer);
while (numBytesRead != -1) {
    fileOutputStream.write(buffer, 0, numBytesRead);
    numBytesRead = fileInputStream.read(buffer);
}
like image 153
ug_ Avatar answered Oct 17 '22 23:10

ug_


My interest of piqued I wrote this little test:

public static void main(String[] args) throws IOException {

    FileInputStream fileInputStream = new FileInputStream("/home/nick/foo");
    FileOutputStream fileOutputStream = new FileOutputStream("/home/nick/bar");
    fileOutputStream.write(fileInputStream.read());

    fileOutputStream.flush();
    fileOutputStream.close();
    fileInputStream.close();
}

It worked as expected - read a single byte from /home/nick/foo and wrote it to /home/nick/bar

EDIT:

Updated program:

public static void main(String[] args) throws IOException {

    FileInputStream fileInputStream = new FileInputStream("/home/nick/foo");
    FileOutputStream fileOutputStream = new FileOutputStream("/home/nick/bar");
    while (fileInputStream.available()>0) {    
        fileOutputStream.write(fileInputStream.read());
    }

    fileOutputStream.flush();
    fileOutputStream.close();
    fileInputStream.close();
}

Copied the entire file. (note - I would not recommend copying a file a byte at a time, use the Buffered I/O classes to copy whole chunks)

Did you by any chance forget to flush() and close() to OutputStream?

like image 20
NickJ Avatar answered Oct 17 '22 21:10

NickJ