方法一:字符串文件流不生成本地文件
FTPClient ftpClient = new FTPClient();
try {
InputStream is = null;
// 1.输入流
is = new ByteArrayInputStream(fileContent.getBytes()); //字节数组
// 2.连接服务器
ftpClient.connect(server);
// 3.登录ftp
ftpClient.login(userName, userPassword);
// 4.指定写入的目录
ftpClient.changeWorkingDirectory(remotePath); //远程路径不存在则创建
// 5.写操作
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //传输模式
ftpClient.enterLocalPassiveMode();
ftpClient.storeFile(new String(fileName.getBytes("utf-8"),"iso-8859-1"), is);
is.close();
} catch (Exception e) {
result = false;
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (Exception e) {
result = false;
}
}
}
FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
Q:用FTPClient,执行到ftp.storeFile(fileName, inputFile);无反应了
A: ftpclient.enterLocalPassiveMode();
ftp.storeFile(fileName, inputFile);问题解决
原因是:FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。 PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请 求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端在命令链路上用PORT 命令告诉服务器:“我打开了XXXX端口,你过来连接我”。于是服务器从20端口向客户端的 XXXX端口发送连接请求,建立一条数据链路来传送数据。 PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请 求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器在命令链路上用PASV 命令告诉客户端:“我打开了XXXX端口,你过来连接我”。于是客户端向服务器的XXXX端口 发送连接请求,建立一条数据链路来传送数据。
方法二:本地文件上传远程服务器
public void uploadFile(String remotePath, String localPath, String fileNames)
throws Exception {
if (connectServer()) {
logger.info("开始[" + localPath + "]SFTP传输到[" + remotePath + "]");
OutputStream outstream = null;
InputStream instream = null;
try {
instream = new FileInputStream(new File(localPath + fileNames));
outstream = this.channel.put(remotePath + fileNames);
byte[] b = new byte[1024];
int n;
while ((n = instream.read(b)) != -1) {
outstream.write(b, 0, n);
}
outstream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeServer();
}
logger.info("结束[" + localPath + "]SFTP传输到[" + remotePath + "]");
} else {
throw new Exception("SFTP连接失败");
}
}