import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.apache.log4j.Logger; import java.io.*; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; /** * FTPClient工具类 */ public class FTPUtils { private static Logger log = Logger.getLogger(FTPUtils.class); private FTPClient ftp; public FTPUtils() { ftp = new FTPClient(); ftp.setControlEncoding("UTF-8"); //解决上传文件时文件名乱码 } public FTPUtils(String controlEncoding) { ftp = new FTPClient(); ftp.setControlEncoding(controlEncoding); //解决上传文件时文件名乱码 } /** * 设置连接超时时间 * @param defaultTimeoutSecond * @param connectTimeoutSecond * @param dataTimeoutSecond */ public void setTimeOut(int defaultTimeoutSecond, int connectTimeoutSecond, int dataTimeoutSecond){ try { ftp.setDefaultTimeout(defaultTimeoutSecond * 1000); //ftp.setConnectTimeout(connectTimeoutSecond * 1000); //commons-net-3.5.jar ftp.setSoTimeout(connectTimeoutSecond * 1000); //commons-net-1.4.1.jar 连接后才能设置 ftp.setDataTimeout(dataTimeoutSecond * 1000); } catch (SocketException e) { log.error("setTimeout Exception:", e); } } public FTPClient getFTPClient(){ return ftp; } public void setControlEncoding(String charset){ ftp.setControlEncoding(charset); } public void setFileType(int fileType) throws IOException { ftp.setFileType(fileType); } /** * 连接FTP服务器 * @param host 主机ip * @param port 端口号 * @param user 用户名 * @param password 密码 * @return * @throws IOException */ public FTPClient connect(String host, int port, String user, String password) throws IOException { try { ftp.connect(host, port); } catch (UnknownHostException ex) { throw new IOException("Can't find FTP server '" + host + "'"); } int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { disconnect(); throw new IOException("Can't connect to server '" + host + "'"); } if ("".equals(user)) { user = "anonymous"; } if (!ftp.login(user, password)) { disconnect(); throw new IOException("Can't login to server '" + host + "'"); } ftp.setFileType(FTP.BINARY_FILE_TYPE); ftp.enterLocalPassiveMode(); return ftp; } /** * 验证是否已连接FTP服务器 * @return true or false */ public boolean isConnected() { return ftp.isConnected(); } /** * 断开与FTP服务器的连接 * @throws IOException */ public void disconnect() throws IOException { if (ftp.isConnected()) { try { ftp.logout(); ftp.disconnect(); } catch (IOException ex) { } } } /** * 从FTP服务器上下载文件 * @param ftpFileName 下载文件名 * @param out 输出流 * @throws IOException */ public void retrieveFile(String ftpFileName, OutputStream out) throws IOException { try { FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName); if (fileInfoArray == null || fileInfoArray.length == 0) { throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server."); } FTPFile fileInfo = fileInfoArray[0]; long size = fileInfo.getSize(); if (size > Integer.MAX_VALUE) { throw new IOException("File '" + ftpFileName + "' is too large."); } if (!ftp.retrieveFile(ftpFileName, out)) { throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path."); } out.flush(); } finally { if (out != null) { try { out.close(); } catch (IOException ex) { } } } } /** * 上传文件输入流 * @param ftpFileName 文件名 * @param in 输入流 * @throws IOException */ public void storeFile(String ftpFileName, InputStream in) throws IOException { try { if (!ftp.storeFile(ftpFileName, in)) { throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path."); } } finally { try { in.close(); } catch (IOException ex) { } } } /** * 修改名称 * @param from 原名 * @param to 新名 * @throws IOException */ public boolean rename(String from, String to) throws IOException { return ftp.rename(from, to); } /** * 删除文件 * @param ftpFileName 文件名 * @throws IOException */ public void deleteFile(String ftpFileName) throws IOException { if (!ftp.deleteFile(ftpFileName)) { throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server."); } } /** * 更新FTP服务器上已存在的文件 * @param ftpFileName 文件名 * @param localFile 本地文件 * @throws IOException */ public void upload(String ftpFileName, File localFile) throws IOException { if (!localFile.exists()) { throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist."); } InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(localFile)); if (!ftp.storeFile(ftpFileName, in)) { throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path."); } } finally { try { in.close(); } catch (IOException ex) { } } } /** * 上传目录(会覆盖) * @param remotePath 远程目录 /home/test/a * @param localPath 本地目录 D:/test/a * @throws IOException */ public void uploadDir(String remotePath, String localPath) throws IOException { File file = new File(localPath); if (file.exists()) { if(!ftp.changeWorkingDirectory(remotePath)){ ftp.makeDirectory(remotePath); //创建成功返回true,失败(已存在)返回false ftp.changeWorkingDirectory(remotePath); //切换成返回true,失败(不存在)返回false } File[] files = file.listFiles(); for (File f : files) { if (f.isDirectory() && !f.getName().equals(".") && !f.getName().equals("..")) { uploadDir(remotePath + "/" + f.getName(), f.getPath()); } else if (f.isFile()) { upload(remotePath + "/" + f.getName(), f); } } } } /** * 从FTP上下载文件 * @param ftpFileName server file name (with absolute path) * @param localFile local file to download into * @throws IOException on I/O errors */ public void download(String ftpFileName, File localFile) throws IOException { OutputStream out = null; try { FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName); if (fileInfoArray == null || fileInfoArray.length == 0) { throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server."); } FTPFile fileInfo = fileInfoArray[0]; long size = fileInfo.getSize(); if (size > Integer.MAX_VALUE) { throw new IOException("File " + ftpFileName + " is too large."); } out = new BufferedOutputStream(new FileOutputStream(localFile)); if (!ftp.retrieveFile(ftpFileName, out)) { throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path."); } out.flush(); } finally { if (out != null) { try { out.close(); } catch (IOException ex) { } } } } /** * 下载目录(会覆盖) * @param remotePath 远程目录 /home/test/a * @param localPath 本地目录 D:/test/a * @return * @throws IOException */ public void downloadDir(String remotePath, String localPath) throws IOException { File file = new File(localPath); if(!file.exists()){ file.mkdirs(); } FTPFile[] ftpFiles = ftp.listFiles(remotePath); for (int i = 0; ftpFiles!=null && i<ftpFiles.length; i++) { FTPFile ftpFile = ftpFiles[i]; if (ftpFile.isDirectory() && !ftpFile.getName().equals(".") && !ftpFile.getName().equals("..")) { downloadDir(remotePath + "/" + ftpFile.getName(), localPath + "/" + ftpFile.getName()); } else { download(remotePath + "/" + ftpFile.getName(), new File(localPath + "/" + ftpFile.getName())); } } } /** * 获取FTP指定目录下的所有文件名 * @param filePath absolute path on the server * @return files relative names list * @throws IOException */ public List<String> listFileNames(String filePath) throws IOException { List<String> fileList = new ArrayList<>(); FTPFile[] ftpFiles = ftp.listFiles(filePath); for (int i = 0; ftpFiles!=null && i<ftpFiles.length; i++) { FTPFile ftpFile = ftpFiles[i]; if (ftpFile.isFile()) { fileList.add(ftpFile.getName()); } } return fileList; } /** * 获取FTP指定目录下所有文件 * @param filePath directory * @return list * @throws IOException */ public List<FTPFile> listFiles(String filePath) throws IOException { List<FTPFile> fileList = new ArrayList<>(); FTPFile[] ftpFiles = ftp.listFiles(filePath); for (int i = 0; ftpFiles!=null && i<ftpFiles.length; i++) { FTPFile ftpFile = ftpFiles[i]; // FfpFileInfo fi = new FfpFileInfo(); // fi.setName(ftpFile.getName()); // fi.setSize(ftpFile.getSize()); // fi.setTimestamp(ftpFile.getTimestamp()); // fi.setType(ftpFile.isDirectory()); fileList.add(ftpFile); } return fileList; } /** * 向FTP服务器发送指定命令 * @param args 操作指令字符串 * @throws IOException */ public void sendSiteCommand(String args) throws IOException { if (ftp.isConnected()) { try { ftp.sendSiteCommand(args); } catch (IOException ex) { } } } /** * 返回FTP所在当前目录字符串 * @return current directory */ public String printWorkingDirectory() { if (!ftp.isConnected()) { return ""; } try { return ftp.printWorkingDirectory(); } catch (IOException e) { } return ""; } /** * 更改FTP所在当前目录 * @param dir 目录地址 * @return true, if working directory changed */ public boolean changeWorkingDirectory(String dir) { if (!ftp.isConnected()) { return false; } try { return ftp.changeWorkingDirectory(dir); } catch (IOException e) { } return false; } /** * 移动当前目录至父目录 * @return */ public boolean changeToParentDirectory() { if (!ftp.isConnected()) { return false; } try { return ftp.changeToParentDirectory(); } catch (IOException e) { } return false; } /** * 打印当前目录的父目录 * @return 父目录的路径字符串 */ public String printParentDirectory() { if (!ftp.isConnected()) { return ""; } String w = printWorkingDirectory(); changeToParentDirectory(); String p = printWorkingDirectory(); changeWorkingDirectory(w); return p; } /** * 创建目录 * @param pathname 目录名 * @throws IOException */ public boolean makeDirectory(String pathname) throws IOException { return ftp.makeDirectory(pathname); } /** * main方法测试工具类 * @param args * @throws Exception */ public static void main(String[] args) throws Exception { FTPUtils ftpUtil = new FTPUtils("UTF-8"); ftpUtil.connect("127.0.0.1", 21, "user", "123456"); File file = new File("D:\\soft\\VSCodeUserSetup-x64-1.44.2.exe"); ftpUtil.upload("VSCode.exe",file); String s = ftpUtil.printWorkingDirectory(); List<String> strings = ftpUtil.listFileNames(s); System.out.println(strings.toString()); //ftpUtil.setTimeOut(60, 60, 60); /*ftpUtil.upload("/home/testuser/文件1.txt", new File("E:/image/FTPClient/FTPClient测试/文件1.txt")); ftpUtil.download("/home/testuser/文件1.txt", new File("E:/image/FTPClient/FTPClient测试/文件1.txt")); ftpUtil.uploadDir("/home/testuser/FTPClient测试", "E:/image/FTPClient/FTPClient测试"); ftpUtil.downloadDir("/home/testuser/FTPClient测试", "E:/image/FTPClient/FTPClient测试"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); //自动增长 ftpUtil.retrieveFile("/home/testuser/文件1.txt", bos); System.out.println(bos.size()); String contentStr = new String(bos.toByteArray(),"GBK"); System.out.println(contentStr); ftpUtil.disconnect();*/ } }