使用Apache Commons的FTPClient执行“RETR” FTP命令。

huangapple 未分类评论58阅读模式
英文:

Use "RETR" FTP command with Apache Common's FTPClient

问题

我正在开发一个Android应用程序(Java 8,目标API = 27),该应用程序从FTP服务器下载文件(使用Apache Commons的FTPClient),但在使用retrieveFileretrieveFileStream方法时遇到了严重的问题,文件字节丢失问题。

这就是为什么我想尝试发送实际的命令的替代方法:

// 登录
String path = remoteFolder + "/" + filename;

if (ftpClient.isConnected()) {
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 用于图像等...
    ftpClient.retr(path); // 发送“RETR”命令

    String reply = ftpClient.getReplyString();
    Log.d(TAG, reply);
}

这会打印:

150 Opening BINARY mode data connection.

但是接下来呢?

ftpClient.getReplyStrings().length1,并且内容相同。通常我会在命令套接字上发送RETR命令,然后读取数据套接字的回复(例如txt文件的内容),但在这个库中似乎没有不同的、可直接访问的套接字。

问题: 如何手动获取文件的内容 - 即使用FTP命令,但不使用retrieveFile...方法(如果可能的话)?

英文:

I'm working on an Android app (Java 8, target API=27) that downloads files from an FTP server (using Apache Common's FTPClient) but I'm experiencing a big problem with missing bytes with the retrieveFile and retrieveFileStream methods.

That's why I want to try the alternative of sending the actual commands:

//login
String path = remoteFolder + "/" + filename;

if(ftpClient.isConnected()) {
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE); //For images,...
    ftpClient.retr(path); //sends the "RETR" command

    String reply = ftpClient.getReplyString();
    Log.d(TAG,reply);
}

This prints:

150 Opening BINARY mode data connection.

But what now?

ftpClient.getReplyStrings().length is 1 and it's the same text. Usually I'd send the RETR command on the command socket, then read the data socket's reply (= the contents of the e.g. txt file) but there don't seem to be different, openly accesible sockets in this library.

Question: How do I get the contents of the file "manually" - so using the FTP commands but without using the retrieveFile... methods (if possible)?

答案1

得分: 0

在发送RETR之前,您需要发送PASVEPSVPORTEPRT,并解析其响应。通常情况下,您会使用PASV,其中有FTP.pasv方法可用。

接下来需要根据PASV的响应来打开数据连接(只有在这之后才发送RETR)。

但是实现数据连接是很多工作。而且FTPClient数据连接的实现被隐藏在受保护的_openDataConnection_方法中。因此您无法重用标准实现。您将需要使用通用的Socket

然后您才可以调用FTP.retr(它本身并不做太多事情)。


这完全是一个不好的主意。但如果您想这样做,请检查FTPClient.retrieveFile的实现 - 一切都在那里。

FTPClient.retrieveFileFTPClient.retrieveFileStream方法工作得非常好 - 它们被成千上万人使用 - 这可能是最广泛使用的Java FTP库。如果对您不起作用,要么是因为您在使用时出现了问题,要么是因为您的网络或服务器出现了问题。

英文:

Before sending RETR, you need to send PASV, EPSV, PORT or EPRT and parse its response. Typically you would use PASV, for which there's FTP.pasv method.

The next would to be open the data connection, based on the response to the PASV (and only then you send RETR).

But implementing the data connection is lot of work. And the FTPClient implementation of the data connection is hidden in a protected _openDataConnection_ method. So you cannot reuse the standard implementation. You will have to use generic Socket class.

And only then you can call FTP.retr (which does not do much on its own).


This is all a bad idea. But if you want to do it, check the implementation of FTPClient.retrieveFile – It's all there.

The FTPClient.retrieveFile and FTPClient.retrieveFileStream methods work perfectly – They are being used by thousands – It's probably the most widely used FTP library for Java. If it does not work for you, it's either because you are using them incorrectly or because there's something wrong with your network or servers.

huangapple
  • 本文由 发表于 2020年6月5日 19:56:15
  • 转载请务必保留本文链接:https://java.coder-hub.com/62214820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定