赞
踩
sun.net.ftp.FtpClient
org.apache.commons.net.ftp.FTPClient
下面分别介绍两个类的使用
如果自己ftp 服务器略过此过程
如果搭建ftp 服务器可以百度一下,有很多的教程,这里就不再描述了
最后搞到 账号 密码 IP 端口 这些就基本够用了,windows ftp服务器可视化界面非常简单
开始之前一定要了解什么是ftp 的主动被动模式,要不然开发过程会遇到很多问题,不知道怎么入手
主动模式:
FTP客户端使用N(N>1023)端口连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,客户端开放N+1端口,发送 PORT命令到FTP服务器,告诉服务器客户端采用主动模式并开放端口;FTP服务器收到PORT主动模式命令和端口号后,通过服务器的20端口和客户端开放的端口连接,发送数据.
被动模式:
FTP客户端使用N(N>1023)连接FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,发送PASV命令到FTP服务器, 服务器在本地开放一个端口(1024以上),然后把开放的端口告诉客户端, 客户端再通过N+1端口连接到服务器开放的端口进行数据传输
更详细的答案可以百度搜一下
主动和被动的区别就是传输端口不一致的问题,开发过程中可能会因为防火墙造成无法进行文件传输等问题
FtpClient client = FtpClient.create();
//client.enablePassiveMode(true);//主动模式
SocketAddress socketAddress = new InetSocketAddress(ip, 端口);
client.setConnectTimeout(timeOut);
client.setReadTimeout(timeOut);
client.connect(socketAddress);
client.login(userName, pass.toCharArray());//登录
FtpReplyCode ftpReplyCode = client.getLastReplyCode();
log.info("连接信息 {}", ftpReplyCode);
if (!ftpReplyCode.isPositiveCompletion()) {
log.error("ftp 连接失败");
throw new FtpLoginException("ftp连接失败");
}
try {
client.changeDirectory(rootDir);
} catch (FtpProtocolException | IllegalArgumentException exception) {
log.error("文件夹不存在进行创建 ", rootDir);
client.makeDirectory(rootDir);
client.changeDirectory(rootDir);
}
InputStream in = getDownIn(filPath); assert null == in : "下载失败"; try { client.setBinaryType(); client.putFile(fileName, in); } catch (Exception e) { log.error(e.getMessage(),e); throw new Exception("上传失败"); } finally { if (null != in) { in.close(); } }
client.close();
然后本地测试是没有问题的,连接远程ftp时,发现登录成功,但是上传文件的时候一直 超时
java.net.ConnectException: Connection timed out: connect
然后经过排查和验证发现是端口的问题,这里还要说一下sun.net.ftp.FtpClient 只有被动模式,没有主动模式,他设置模式的方法是
client.enablePassiveMode(true)
- 1
但是看原来发现这个方法没啥用
public sun.net.ftp.FtpClient enablePassiveMode(boolean var1) {
return this;
}
可以看到final修饰
public class FtpClient extends sun.net.ftp.FtpClient {
private final boolean passiveMode = true;
所以不推荐使用这个类库
gradle implementation("commons-net","commons-net","3.7.2")
FTPClient client = new FTPClient();
client.enterLocalActiveMode();//主动
client.enterLocalPassiveMode();//被动
InetAddress inetAddress = InetAddress.getByName(host);
client.connect(inetAddress,port);
boolean isLogin = client.login(userName,pass);
if(isLogin){
log.info("ftp {} 登录成功",userName);
return this;
}
log.error("ftp {} 登录失败",userName);
throw new IOException("ftp 登录失败");
String rootDir = new String(rootDir.getBytes("GBK"),"iso-8859-1");
client.makeDirectory(rootDir);
client.changeWorkingDirectory(rootDir);
new String(rootDir.getBytes(“GBK”),“iso-8859-1”); 这句是为了显示中文
boolean flag = client.storeFile( new String(fileName.getBytes("GBK"),"iso-8859-1"),inputStream);
inputStream.close();
client.disconnect();
经测试出色完成任务,这个类库还有很多方法,可以根据自己的需要看一看
org.apache.commons.net.MalformedServerReplyException:
Truncated server reply: '220 '
这个错误不影响连接
捕获这个错误继续操作就行,220代表已经连接成功了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。