一.代码
1.打开ftp服务器:slyar ftpserver
2.导入jar包:commons-net-1.4.1.jar
3.util代码
package com.scent.ftp; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.apache.log4j.Logger; /** * 提供上传图片文件, 文件夹 * @author MYMOON * */ public class FtpUtils { private static Logger logger = Logger.getLogger(FtpUtils.class.getName()); private ThreadLocal<FTPClient> ftpClientThreadLocal = new ThreadLocal<FTPClient>(); private String encoding = "UTF-8"; private int clientTimeout = 1000 * 30; private boolean binaryTransfer = true; private String host; private int port; private String username; private String password; private FTPClient getFTPClient() { if (ftpClientThreadLocal.get() != null && ftpClientThreadLocal.get().isConnected()) { return ftpClientThreadLocal.get(); } else { FTPClient ftpClient = new FTPClient(); // 构造一个FtpClient实例 ftpClient.setControlEncoding(encoding); // 设置字符集 try { connect(ftpClient); // 连接到ftp服务器 setFileType(ftpClient); //设置文件传输类型 ftpClient.setSoTimeout(clientTimeout); } catch (Exception e) { e.printStackTrace(); } ftpClientThreadLocal.set(ftpClient); return ftpClient; } } /** * 连接到ftp服务器 */ private boolean connect(FTPClient ftpClient) throws Exception { try { ftpClient.connect(host, port); // 连接后检测返回码来校验连接是否成功 int reply = ftpClient.getReplyCode(); if (FTPReply.isPositiveCompletion(reply)) { //登陆到ftp服务器 if (ftpClient.login(username, password)) { return true; } } else { ftpClient.disconnect(); throw new Exception("FTP server refused connection."); } } catch (IOException e) { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); //断开连接 } catch (IOException e1) { throw new Exception("Could not disconnect from server.", e1); } } throw new Exception("Could not connect to server.", e); } return false; } /** * 断开ftp连接 */ public void disconnect() throws Exception { try { FTPClient ftpClient = getFTPClient(); ftpClient.logout(); if (ftpClient.isConnected()) { ftpClient.disconnect(); ftpClient = null; } } catch (IOException e) { throw new Exception("Could not disconnect from server.", e); } } /** * 设置文件传输类型 * * @throws FTPClientException * @throws IOException */ private void setFileType(FTPClient ftpClient) throws Exception { try { if (binaryTransfer) { ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); } else { ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE); } } catch (IOException e) { throw new Exception("Could not to set file type.", e); } } //--------------------------------------------------------------------- // public method //--------------------------------------------------------------------- /** * 上传一个本地文件到远程指定文件 * * @param remoteDir 远程文件名(包括完整路径) * @param localAbsoluteFile 本地文件名(包括完整路径) * @param autoClose 是否自动关闭当前连接 * @return 成功时,返回true,失败返回false * @throws FTPClientException */ public boolean uploadFile(String localAbsoluteFile, String remoteDir, String filename) throws Exception { BufferedInputStream input = null; boolean success = false; try { getFTPClient().makeDirectory(remoteDir); getFTPClient().changeWorkingDirectory(remoteDir);// 改变工作路径 // 处理传输 File localFile = new File(localAbsoluteFile); input = new BufferedInputStream(new FileInputStream(localFile)); logger.info(localFile.getName() + "开始上传....."); FTPClient ftpClient = getFTPClient(); // String remote = remoteDir+filename; //localFile.getName() = 1.jpg改成localAbsoluteFile = C:UsersJohnDesktop2221.jpg就失败 String localFileName = localFile.getName(); success = getFTPClient().storeFile(filename, input); if(success == true){ logger.info(filename + "上传成功"); return success; } } catch (FileNotFoundException e) { throw new Exception("local file not found.", e); } catch (IOException e) { throw new Exception("Could not put file to server.", e); } finally { try { if (input != null) { input.close(); } } catch (Exception e) { throw new Exception("Couldn't close FileInputStream.", e); } } return success; } /*** * @上传文件夹 * @param localDirectory 当地文件夹 * @param remoteDirectoryPath Ftp 服务器路径 以目录"/"结束 * */ private boolean uploadDirectory(String localDirectory, String remoteDirectoryPath) { File src = new File(localDirectory); try { getFTPClient().makeDirectory(remoteDirectoryPath); } catch (IOException e) { e.printStackTrace(); logger.info(remoteDirectoryPath + "目录创建失败"); } File[] allFile = src.listFiles(); for (int currentFile = 0; currentFile < allFile.length; currentFile++) { if (!allFile[currentFile].isDirectory()) { //C:UsersJohnDesktop2221.jpg String srcName = allFile[currentFile].getPath().toString(); File file = new File(srcName); String remote = remoteDirectoryPath; uploadFile(file, remote); } } for (int currentFile = 0; currentFile < allFile.length; currentFile++) { if (allFile[currentFile].isDirectory()) { // 递归 uploadDirectory(allFile[currentFile].getPath().toString(), remoteDirectoryPath); } } return true; } /*** * 上传Ftp文件 配合文件夹上传 * @param localFile 当地文件 * @param romotUpLoadePath上传服务器路径 * - 应该以/结束 * */ public boolean uploadFile(File localFile, String romotUpLoadePath) { BufferedInputStream inStream = null; boolean success = false; try { getFTPClient().changeWorkingDirectory(romotUpLoadePath);// 改变工作路径 inStream = new BufferedInputStream(new FileInputStream(localFile)); logger.info(localFile.getName() + "开始上传....."); success = getFTPClient().storeFile(localFile.getName(), inStream); if (success == true) { logger.info(localFile.getName() + "上传成功"); return success; } } catch (FileNotFoundException e) { e.printStackTrace(); logger.error(localFile + "未找到"); } catch (IOException e) { e.printStackTrace(); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return success; } public String[] listNames(String remotePath, boolean autoClose) throws Exception{ try { String[] listNames = getFTPClient().listNames(remotePath); return listNames; } catch (IOException e) { throw new Exception("列出远程目录下所有的文件时出现异常", e); } finally { if (autoClose) { disconnect(); //关闭链接 } } } public String getEncoding() { return encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public int getClientTimeout() { return clientTimeout; } public void setClientTimeout(int clientTimeout) { this.clientTimeout = clientTimeout; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isBinaryTransfer() { return binaryTransfer; } public void setBinaryTransfer(boolean binaryTransfer) { this.binaryTransfer = binaryTransfer; } /** * 目标路径 按年月存图片: 201405 * 限时打折 /scenery/ ticket, hotel, catering * 浪漫之游 /discount/ * * @param args */ /* public static void main(String[] args) { FtpUtils ftp = new FtpUtils(); ftp.setHost("192.168.1.121"); ftp.setPort(21); ftp.setUsername("LJR"); ftp.setPassword("123456"); try { // 上传整个目录 // ftp.uploadDirectory("F:/tmp/njff/", "/noff/"); // 上传单个文件 boolean rs = ftp.uploadFile("D:/2.jpg", "/201301/", "02.jpg"); System.out.println(">>>>>>> " + rs); // 列表 String[] listNames = ftp.listNames("/", true); System.out.println(Arrays.asList(listNames)); ftp.disconnect(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } */ }
4.调用代码
FtpUtils ftp = new FtpUtils(); ftp.setHost("192.168.1.000"); ftp.setPort(28);//默认端口为21 ftp.setUsername("wa"); ftp.setPassword("123a"); try { // 上传整个目录 // ftp.uploadDirectory("C:\Users\John\Desktop\222", "/201301/"); //上传单个文件 boolean rs = ftp.uploadFile("C:\Users\John\Desktop\222\1.jpg", "/201302/","1.jpg"); System.out.println(">>>>>>> " + rs); // 列表 // String[] listNames = ftp.listNames("/", true); // System.out.println(Arrays.asList(listNames)); ftp.disconnect();
二.FTPClient.storeFile返回false的原因
Debug搞了一晚上,什么都看过了,最后总算是自己茅塞顿开发现了问题。 FTPClient会返回false的原因有很多,
首先有编码错误的,要加上: ftpClient.setControlEncoding("UTF-8");
其次有没有启动被动模式的: ftpClient.enterLocalPassiveMode();
但要是到这里你还是没解决问题的话,你就要按这个步骤排查一下问题了:
请你尝试一下用浏览器/资源管理器/其他ftp客户端进入你的ftp的ip地址,如果进不去那就可能是ftp没有打开或者服务器有防火墙你没设置好端口。
如果你可以进入ftp的ip地址并查看里面的内容,说明ftp链接正常,那么好好看看你的ftpClient.changeWorkingDirectory(path)里的path参数是什么吧,然后到相应的服务器去查看ftp文件夹的权限,如图:
这样问题就很明显了,我上传的文件夹的所属仍然是root的,而不是我自己定义的ftp的用户,那么我肯定会上传不上去。 这时候只要
便完事了。
https://www.cnblogs.com/peterYong/p/6596667.html