Java FTPClient(apache commons)storefile()成功上传文件,然后超时..?

时间:2014-05-01 19:18:04

标签: java ftp apache-commons-net

以下是我必须将文件上传到FTP服务器的一些代码:

private boolean ftpSend(byte[] fileBytes, String filename, HashMap<String, String> endpointAddressData) throws Exception {
    boolean success = false;

    String login = endpointAddressData.get("user");
    String hostname = endpointAddressData.get("host");
    String password = endpointAddressData.get("password");

    String portString = endpointAddressData.get("port");
    int port = (portString == null) ? 21 : Integer.parseInt(portString);

    FTPClient ftpClient = new FTPClient();
    ByteArrayInputStream inputStream = null;
    try {
        ftpClient.setConnectTimeout(10000);
        ftpClient.connect(hostname, port);

        int reply = ftpClient.getReplyCode();

        if(!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();

            throw new Exception("FTP server " + hostname + " refused connection.");
        }

        if (password != null) {
            ftpClient.login(login, password);
        } else {
            ftpClient.user(login);
        }

        logger_.debug("FTP - Writing: " + ftpClient.printWorkingDirectory() + "/" + filename + " on host " + endpointAddressData.get("host"));

        inputStream = new ByteArrayInputStream(fileBytes);
        success = ftpClient.storeFile(filename, inputStream);
        inputStream.close();
        success = success && ftpClient.completePendingCommand();

        logger_.debug("FTP - Completed: " + ftpClient.printWorkingDirectory() + "/" + filename + " on host " + endpointAddressData.get("host"));

        ftpClient.disconnect();

    } catch (Exception ex) {
        success = false;

        logger_.error("An error occurred during FTP upload to " + endpointAddressData.get("host") + ".", ex);
    } finally {
        if (ftpClient.isConnected()) {
            ftpClient.abort();
            ftpClient.disconnect();
        }

        if (inputStream != null) {
            inputStream.close();
        }

        return success;
    }
}

当我使用一些测试数据运行它时,上传显然成功完成(这是FTP服务器日志):

(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> USER ######
(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> 331 Password required for ######
(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> PASS ########
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 230 Logged on
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> PWD ########
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 257 "/" is current directory.
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> PORT 127,0,0,1,250,242
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 200 Port command successful
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> STOR testFTP1.txt
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 150 Opening data channel for file upload to server of "/testFTP1.txt"
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 226 Successfully transferred "/testFTP1.txt"
(000009)01/05/2014 12:15:10 PM - anonymous (127.0.0.1)> 421 Connection timed out.
(000009)01/05/2014 12:15:10 PM - anonymous (127.0.0.1)> disconnected.

我做错了什么?

2 个答案:

答案 0 :(得分:2)

在调试器中单步执行后,我发现ftpClient.completePendingCommand()调用导致超时。我猜这个命令已经完成,它正无限期地等待下一个命令。我评论说该行和代码很容易完成。

来自FTPClient上的JavaDoc: http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#completePendingCommand()

  

有一些FTPClient方法无法完成整个FTP事务序列以完成事务。这些命令在接收到正中间命令后需要程序员采取一些动作。程序员代码完成其操作后,必须调用此方法从服务器接收完成答复并验证整个事务是否成功。

我猜storeFile()(FTP STOR命令)不是这些方法之一。

答案 1 :(得分:0)

我有一个代码有同样的问题。我使用代码下载各种文件,但其中一个文件无限期地停在同一行,所以我只是把它放在一个单独的线程中并加入完成一段时间而不是注释掉它。现在一切似乎都运转正常。 所以它会是这样的:

//right after the downloading part is finished
Thread connectionFinilizerThread = new Thread() {
    public void run() {
        try {
            boolean success= client.completePendingCommand();
            if (success) {
                logger.info("success");
            }
            else{
                logger.error("failure");
            }
        } catch (IOException e) {
        }
    }
}
connectionFinilizerThread.start();
try {
    connectionFinilizerThread.join(20000);
} catch (InterruptedException e) {

}