How to transfer using FTP streams

Sometimes it is useful to be able to read from or write to the FTP server as if it were a InputStream or OutputStream. This is possible using FTPInputStream and FTPOutputStream, and SSHFTPInputStream and SSHFTPOutputStream. These classes directly Java's InputStream and OutputStream, and can be used in exactly the same manner.

An instance of FTPClient, SSLFTPClient, or SSHFTPClient or a subclass must be supplied to the stream's constructor. The InputStreams have an optional parameter for an offset to begin reading from, which is only applicable for binary transfers. The streams can only be used for one data transfer. As is standard for streams, it is essential that the stream is closed when the transfer is complete, even if an exception was thrown. This is best done in a finally block as soon in the example below. Otherwise, resources may not be correctly cleaned up.

All of the stream's transfer parameters are taken from the FTP client instance that is supplied to the constructor. For example, if the stream is to be a binary mode transfer, binary mode must be set in the instance before it is supplied to the constructor.

The following shows how an FTPInputStream can be used to download a file:

FTPInputStream in = new FTPInputStream(ftp, "myfile.zip");
BufferedOutputStream out = null;
byte[] chunk = new byte[4096];
int count = 0;
try {
out = new BufferedOutputStream(new FileOutputStream("myfile.zip"));
while ((count = in.read(chunk)) >= 0) {
    out.write(chunk, 0, count);
}
}
finally {
try {
    in.close();
}
catch (Exception ex) {
    ex.printStackTrace();
}
if (out != null) {
    try {
        out.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
}

Streams can be especially useful when a large file is being downloaded and the stream needs to be processed as it arrives. For example, if an XML file was being downloaded, a SAX parser could parse the stream.