算是一个工具类吧,网上示例挺多,贴一个看到的比较好的示例,修改了很小一部分有问题的地方,并附上链接。中间比较恶心的是没有判定目录是否存在的api,只能通过枚举进行判断。
一、引入依赖
<!--commons-net --> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.5</version> </dependency>
二、创建工具类FtpUtils
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 java.io.*; import java.net.MalformedURLException; /** * @Auther: hrabbit * @Date: 2018-04-21 下午12:35 * @Description: */ public class FTPUtils { public static FTPClient ftpClient = null; /** * 初始化ftp服务器 */ public static void initFtpClient(String hostname,String username,String password,Integer port) { ftpClient = new FTPClient(); /** * 在上传文件的时候,我们的文件名称有时候需要被保留,但是有时候如果文件名称为中文的话,会产生保存失败的现象,因此只需要将FTPClient的编码方式更改为UTF-8模式即可解决 */ ftpClient.setControlEncoding("utf-8"); try { //连接ftp服务器 ftpClient.connect(hostname, port); //登录ftp服务器 ftpClient.login(username, password); //是否成功登录服务器 int replyCode = ftpClient.getReplyCode(); if(FTPReply.isPositiveCompletion(replyCode)){ System.out.println("ftp服务器登录成功"); } }catch (MalformedURLException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } /** * 上传文件 * @param pathname ftp服务保存地址 * @param fileName 上传到ftp的文件名 * @param inputStream 输入文件流 * @return */ public static boolean uploadFile(String hostname,String username,String password,Integer port, String pathname, String fileName,InputStream inputStream){ boolean flag = false; try{ System.out.println("开始上传文件"); initFtpClient(hostname,username,password,port); /** * 二进制形式上传文件 */ ftpClient.setFileType(FTP.BINARY_FILE_TYPE); /** * 主动模式和被动模式的不同简单概述为: 主动模式传送数据时是“服务器”连接到“客户端”的端口;被动模式传送数据是“客户端”连接到“服务器”的端口。 主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。 被动模式只需要服务器端开放端口给客户端连接就行了。 因此只需要将模式改为被动模式即可: */ ftpClient.enterLocalPassiveMode(); CreateDirecroty(pathname); // ftpClient.makeDirectory(pathname); ftpClient.setControlEncoding("utf-8"); ftpClient.storeFile(fileName, inputStream); System.out.println("上传结束"); inputStream.close(); ftpClient.logout(); flag = true; System.out.println("上传文件成功"); }catch (Exception e) { System.out.println("上传文件失败"); e.printStackTrace(); }finally{ if(ftpClient.isConnected()){ try{ ftpClient.disconnect(); }catch(IOException e){ e.printStackTrace(); } } if(null != inputStream){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return true; } //改变目录路径 public static boolean changeWorkingDirectory(String directory) { boolean flag = true; try { flag = ftpClient.changeWorkingDirectory(directory); if (flag) { System.out.println("进入文件夹" + directory + " 成功!"); } else { System.out.println("进入文件夹" + directory + " 失败!开始创建文件夹"); } } catch (IOException ioe) { ioe.printStackTrace(); } return flag; } //创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建 public static boolean CreateDirecroty(String remote) throws IOException { boolean success = true; String directory = remote + "/"; // 如果远程目录不存在,则递归创建远程服务器目录 if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) { int start = 0; int end = 0; if (directory.startsWith("/")) { start = 1; } else { start = 0; } end = directory.indexOf("/", start); String path = ""; String paths = ""; while (true) { String subDirectory = new String(remote.substring(start, end).getBytes("UTF-8"), "iso-8859-1"); path = path + "/" + subDirectory; if (!existFile(path)) { if (makeDirectory(subDirectory)) { changeWorkingDirectory(subDirectory); } else { System.out.println("创建目录[" + subDirectory + "]失败"); changeWorkingDirectory(subDirectory); } } else { changeWorkingDirectory(subDirectory); } paths = paths + "/" + subDirectory; start = end + 1; end = directory.indexOf("/", start); // 检查所有目录是否创建完毕 if (end <= start) { break; } } } return success; } //判断ftp服务器文件是否存在 public static boolean existFile(String path) throws IOException { boolean flag = false; FTPFile[] ftpFileArr = ftpClient.listFiles(path); if (ftpFileArr.length > 0) { flag = true; } return flag; } //创建目录 public static boolean makeDirectory(String dir) { boolean flag = true; try { flag = ftpClient.makeDirectory(dir); if (flag) { System.out.println("创建文件夹" + dir + " 成功!"); } else { System.out.println("创建文件夹" + dir + " 失败!"); } } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 下载文件 * * @param pathname FTP服务器文件目录 * * @param filename 文件名称 * * @param localpath 下载后的文件路径 * * @return */ public static boolean downloadFile(String hostname,String username,String password,Integer port,String pathname, String filename, String localpath){ boolean flag = false; OutputStream os=null; try { System.out.println("开始下载文件"); initFtpClient(hostname,username,password,port); //切换FTP目录 ftpClient.changeWorkingDirectory(pathname); FTPFile[] ftpFiles = ftpClient.listFiles(); for(FTPFile file : ftpFiles){ if(filename.equalsIgnoreCase(file.getName())){ File localFile = new File(localpath + "/" + file.getName()); os = new FileOutputStream(localFile); ftpClient.retrieveFile(file.getName(), os); os.close(); } } ftpClient.logout(); flag = true; System.out.println("下载文件成功"); } catch (Exception e) { System.out.println("下载文件失败"); e.printStackTrace(); } finally{ if(ftpClient.isConnected()){ try{ ftpClient.disconnect(); }catch(IOException e){ e.printStackTrace(); } } if(null != os){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return flag; } /** * 删除文件 * * @param pathname FTP服务器保存目录 * * @param filename 要删除的文件名称 * * @return */ public static boolean deleteFile(String hostname,String username,String password,Integer port,String pathname, String filename){ boolean flag = false; try { System.out.println("开始删除文件"); initFtpClient(hostname,username,password,port); //切换FTP目录 ftpClient.changeWorkingDirectory(pathname); ftpClient.dele(filename); ftpClient.logout(); flag = true; System.out.println("删除文件成功"); } catch (Exception e) { System.out.println("删除文件失败"); e.printStackTrace(); } finally { if(ftpClient.isConnected()){ try{ ftpClient.disconnect(); }catch(IOException e){ e.printStackTrace(); } } } return flag; } }
三、愉快的使用吧
附链接:https://www.jianshu.com/p/44d9b05691a8
再附一个CSDN的:https://blog.csdn.net/crl2518528/article/details/71266728
四、吐个槽
csdn商业化也太明显了吧,我想搜几本电子书,出来全各种要积分的,以前的开源精神都去哪了,唉~~~