1.引入import org.apache.commons.net.ftp.FTPClient;包
2.上代码
/**
* <p>Discription:[多文件上传FTP方法入口]</p>
* Created on 2017年3月27日 下午7:44:44
* @param sourceFile 本地文件绝对路径
* @param remotePath 远程服务器绝对路径(当远程路径不存在时,自动创建)
* @return int -1:出现异常 0:上传成功
* @author:[全冉]
*/
public int upload(String sourceFile,String remotePath) {
String host ="";
FTPClient ftpClient = new FTPClient();
try {
for (ServerEntity serverEntity : remoteServers) {//本人这里是有两个FTP服务器,所以用for循环
LOG.info("准备链接FTP服务器的参数...");
host = '172.168.32.171';
ftpClient.connect(host, '21');
LOG.info("FTP服务器连接成功,开始登录FTP服务器...");
ftpClient.login("quanran", "123456");
ftpClient.setBufferSize(1024);//设置缓冲区
ftpClient.setControlEncoding("GBK");//设置编码
ftpClient.enterLocalPassiveMode();//;这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置文件类型(二进制)
ftpClient.sendCommand("site umask "+MODE_R_W);//设置权限
refreshFileList(sourceFile, remotePath, ftpClient);
//当全部的文件全部上传到某一个FTP服务器成功后,则关闭FTP客户端
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
LOG.error("关闭FTP客户端出错");
return -1;
}
}
}
} catch (Exception e) {
LOG.info("往Host为:"+host+"的FTP服务器上传文件失败:" + e);
return -1;
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
LOG.error("关闭FTP客户端出错");
return -1;
}
}
}
return 0;
}
/**
* <p>Discription:[根据原目标路径进行递归,依次获取此路径下的文件上传]</p>
* Created on 2017年3月27日 下午3:10:41
* @param filePath 源文件路径的共有路径,不能为空
* @param remotePath 目标路径的共有路径,不能为空
* @param ftpClient 已经登录的FTP服务器实例,不能为空
* @return void
* @author:[全冉]
*/
public void refreshFileList(String filePath, String remotePath, FTPClient ftpClient) throws Exception{
//获取原目标路径下的所有文件
File dir=new File(filePath);
File[] files=dir.listFiles();
if (files == null) {
return ;
}
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
//是文件夹,则递归
refreshFileList(files[i].getAbsolutePath(), remotePath, ftpClient);//递归文件夹!!!
} else {
String sourceFile = files[i].getPath();
String excessivePath = sourceFile.substring(sourceFile.lastIndexOf(File.separator+"assets"+File.separator),sourceFile.length());
String remotePathCurrent = remotePath + excessivePath.substring(0,excessivePath.indexOf(files[i].getName()));
//是文件,则执行上传到FTP方法
process(sourceFile, remotePathCurrent, ftpClient);
}
}
}
/**
* <p>Discription:[将单文件上传到FTP服务器]</p>
* Created on 2017年3月27日 下午3:17:11
* @param sourceFile 本地文件绝对路径
* @param remotePath FTP服务器的存储绝对路径
* @param ftpClient 已经登录的FTP服务器实例,不能为空
* @return void
* @author:[全冉]
*/
private void process(String sourceFile, String remotePath, FTPClient ftpClient) throws Exception{
//对remotePath参数不为空的判断
if (StringUtils.isBlank(remotePath)) {
File file = new File(sourceFile);
remotePath = file.getParent();
}
File file = new File(sourceFile);
if (!file.exists()) {
throw new IOException("文件不存在.");
}
FileInputStream is = new FileInputStream(file);
// 转移工作目录至指定目录下
LOG.info("FTP服务器开始更改操作的目录...");
this.changeMakeWorkingDir(remotePath,ftpClient);
LOG.info("开始往FTP服务器上传文件...");
boolean isFinish = ftpClient.storeFile(new String(file.getName().getBytes("GBK"), "iso-8859-1"), is);
if (isFinish) {
LOG.info("FTP服务器文件["+file.getName()+"]上传成功");
} else {
LOG.info("FTP服务器文件["+file.getName()+"]上传失败");
}
is.close();
}
/**
* <p>Discription:[切换目录,如果目录不存在会自动创建]</p>
* Created on 2015年3月2日
*
* @param path 要切换的工作区路径
* @throws IOException
* @author:[Goma 郭茂茂]
*/
private void changeMakeWorkingDir(String path, FTPClient ftpClient) throws IOException {
String[] dirs = path.split("/"); //TODO File的分隔符 在开发电脑商拆分不开,未知原因
ftpClient.changeWorkingDirectory(new String("/home/website".getBytes("GBK"), "iso-8859-1"));
for (String dir : dirs) {
dir = new String(dir.getBytes("GBK"), "iso-8859-1");
if (dir != null && !"".equals(dir)) {
ftpClient.makeDirectory(dir);//没有就创建目录返回true;已经有了就不创建了,返回fasle
//ftpClient.cdUp();//当前目录上移一层。
}
ftpClient.changeWorkingDirectory(dir);//切换到指定目录
}
}
3.注意:第2步里的最后 ftpClient.changeWorkingDirectory()方法,只有两种切换方法:
(1).继续向当前目录下切换。eg:当前目录是/home/website/html时,用ftpClient.changeWorkingDirectory(“assests/css”) 之后,当前目录就变 为/home/website/html/assests/css。
(2).切换为FTP服务器根目录。eg:当前目录是 /home/website/html/assests/css,用ftpClient.changeWorkingDirectory("/home/website")之后,就切换到了/home/website目 录下。(FTP服务器的根目录是 /home/website )
4.本人就在第3步的这个地方,卡了几个小时,在ftp服务器上生成的目录结构总是不对!最后终于弄明白了。