Dings3
Dings3

Reputation: 3

Incomplete file when downloading with Java from FTP

In my application I upload a byte[] (serialized Object) to my FTP server, which is working perfectly. However when I try to download it only the first part (like 3000 bytes) of the array are correct, the rest is filled with zeros.

I can't seem to figure out what is wrong, any help would be appreciated. I am using the package org.apache.commons.net.*

public static byte[] downloadBoard( String host, int port, String usr, String pwd) throws IOException {
  FTPClient ftpClient = new FTPClient();
  byte[] buf = new byte[20000];

  try {
    ftpClient.connect( host, port );
    ftpClient.login( usr, pwd );

    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    InputStream is = ftpClient.retrieveFileStream("asdf.board");
    is.read(buf);
    is.close();

    ftpClient.completePendingCommand();
    ftpClient.logout();
  } finally {
    ftpClient.disconnect();
  }
  return buf;
}

Upvotes: 0

Views: 2304

Answers (2)

pb2q
pb2q

Reputation: 59607

InputStream.read() typically doesn't read the entire stream for you, only some part of it. Note that InputStream.read() returns the number of bytes actually read, which you'll need to check.

The typical pattern is to loop until the InputStream has reported that no more bytes are available.

Upvotes: 2

Stefan Haustein
Stefan Haustein

Reputation: 18793

is.read() may not return the full content. You'll need to put read() into a loop similar to this:

int pos = 0;
while (true) {
  int count = is.read(buf, pos, buf.length - pos);
  if (count <= 0) {
    break;
  }
  pos += count;
}

P.S.:

If you know the size of the file, you can use a DataInputStream to read the buffer without a loop:

byte[] buf = new byte[exactFileSize];
DataInputStream dis = new DataInputStream(is);
dis.readFully(buf);

Upvotes: 2

Related Questions