我看了很多例子并试图了解我做错了什么但没有成功,也许你可以帮助我。它总是在第二个文件处停止,但第一个文件只是在c:\上创建,大小为0kb。 files_server.get(i)是ArrayList,包含我想下载的所有文件。
我的代码:
public FTPConnection() {
StartD std = new StartD();
std.start();
}
class StartD extends Thread{
@Override
public void run()
{
for (int i = 0; i < files_server.size(); i++) {
err = ftpDownload(files_server.get(i), "C:/"+ files_server.get(i));
if (!err)
{
System.out.println("Error in download, breaking");
break;
}
}
}
public boolean ftpDownload(String srcFilePath, String desFilePath)
{
try {
FileOutputStream desFileStream = new FileOutputStream(desFilePath);
InputStream input = mFTPClient.retrieveFileStream(srcFilePath);
byte[] data = new byte[1024];
int count;
while ((count = input.read(data)) != -1)
{
desFileStream.write(data, 0, count);
}
desFileStream.close();
} catch (Exception e) {
return false;
}
return true;
}}
如果我使用了结尾:
public boolean ftpDownload(String srcFilePath, String desFilePath) {
boolean status = false;
try {
FileOutputStream desFileStream = new FileOutputStream(desFilePath);
status = mFTPClient.retrieveFile(srcFilePath, desFileStream);
desFileStream.close();
return status;
} catch (Exception e) {
}
return status;
}
相反,一切正常,但我无法监控文件下载进度。
答案 0 :(得分:2)
我只使用它来解压缩文件而不是FTP,但是在这种情况下,InputStream缓冲区可以返回零,所以我认为值得尝试将while循环更改为:
while ((count = input.read(data)) >= 0)
public int read(byte [] b)抛出IOException
从输入流中读取一些字节数并将它们存储到缓冲区数组b中。 实际读取的字节数以整数形式返回。这个 方法阻塞直到输入数据可用,检测到文件结尾, 或抛出异常。
如果b的长度为零,则不读取任何字节,返回0;
也可能是你分配了两次计数,这可能会破坏数据的第一个字节:
int count = input.read(data);
while ((count = input.read(data)) != -1)
因此,在声明它时不要指定任何可计数的内容。
答案 1 :(得分:1)
假设您的库是commons-net包中的FTP客户端。要弄清楚你的代码有什么问题并不容易,因为我们无法运行它,因为你的描述(第二个文件停止)是不够的(它会抛出异常吗?它会永远挂起吗?它是否完整而没有任何副作用?)。无论如何,我有几个建议:
CountingOutputStream
(来自Apache commons-io)监控进度ProtocolCommandListener
记录正在进行的操作另请注意,前1024个字节始终丢失。最后,我不知道将文件放在C:\中的安全性与它在服务器上的名称相同。在最好的情况下,它可能会导致许可问题,最坏的情况可能会导致安全漏洞 - 无论如何,如果您对文件名有一定程度的控制权,这并不成立,但是他们会考虑这个建议。
这是一个示例客户端
public class FTP {
public static void main(String[] args) throws SocketException, IOException {
FTPClient client = new FTPClient();
client.addProtocolCommandListener(new ProtocolCommandListener(){
@Override
public void protocolCommandSent(ProtocolCommandEvent evt) {
logger.debug(evt.getMessage());
}
@Override
public void protocolReplyReceived(ProtocolCommandEvent evt) {
logger.debug(evt.getMessage());
}
});
client.connect("ftp.mozilla.org");
client.login("anonymous", "");
client.enterLocalPassiveMode();
OutputStream out = new CountingOutputStream(new NullOutputStream()) {
@Override
public void beforeWrite(int count) {
super.beforeWrite(count);
logger.info("Downloaded " + getCount() + " bytes");
}
};
for (String filename: new String[] {"MD5SUMS", "SHA1SUMS"})
client.retrieveFile("pub/firefox/releases/15.0b4/" + filename, out);
out.close();
client.disconnect();
}
private static Logger logger;
static {
logger = Logger.getLogger(FTP.class.getCanonicalName());
}
}
配置完成后,记录器将输出所有原始套接字会话,它可以帮助您更好地理解问题,只要它在FTP端而不是在应用程序IO中