views:

29

answers:

2

Hi, I am having a web application with an applet which will copy a file packed witht the applet to the client machine.

When I deploy it to webserver and use: InputStream in = getClass().getResourceAsStream("filename") ;

The in.available() always return a size of 8192 bytes for every file I tried, which means the file is corrupted when it is copied to the client computer.

The InputStream is of type HttpInputStream (sun.net.protocol.http.HttpUrlConnection$httpInputStream). But while I test applet in applet viewer, the files are copied fine, with the InputStream returned is of type BufferedInputStream, which has the file's byte sizes. I guess that when getResourceStream in file system the BufferedInputStream will be used and when at http protocol, HttpInputStream will be used.

How will I copy the file completely, is there a size limited for HttpInputStream? Thanks a lot.

+3  A: 

in.available() tells you how many bytes you can read without blocking, not the total number of bytes you can read from a stream.

Here's an example of copying an InputStream to an OutputStream from org.apache.commons.io.IOUtils:

public static long copyLarge(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}
tdavies
Thanks Tdavies, I was able to copy the file.
Khue Vu
+1  A: 

The in.available() always return a size of 8192 bytes for every file I tried, which means the file is corrupted when it is copied to the client computer.

It does not mean that at all!

The in.available() method returns the number of characters that can be read without blocking. It is not the length of the stream. In general, there is no way to determine the length of an InputStream apart from reading (or skipping) all bytes in the stream.

(You may have observed that new FileInputStream("someFile").available() usually gives you the file size. But that behaviour is not guaranteed by the spec, and is certainly untrue for some kinds of file, and possibly for some kinds of file system as well. A better way to get the size of a file is new File("someFile").length(), but even that doesn't work in some cases.)

See @tdavies answer for example code for copying an entire stream's contents. There are also third party libraries that can do this kind of thing; e.g. org.apache.commons.net.io.Util.

Stephen C
Hi, thanks Stephen.
Khue Vu