Appache Ftp使用(二)

来源:互联网 发布:滨波品牌什么档次知乎 编辑:程序博客网 时间:2024/05/22 14:18

Appache  Ftp使用(二)

一:前言

之前已经介绍过Appache Ftp的简单配置和封装,本篇文章将直接进行多个方法功能的封装和组合使用。

二:编写ftp方法实用方法

  • 单个文件下载
    /** * 方法 downloadFile * * @param localFilePath 本地存放下载文件的路径 * @param fileName      ftp上的待下载的文件名 * @param ftpFilePath   ftp远程文件路径 * @return */public boolean downloadFile(String localFilePath, String fileName, String ftpFilePath) {boolean result = false;String message = "";OutputStream is = null;if (ftpClient != null) {log.info("正在下载文件:" + fileName + ",请等待...");// ftp登陆目录下的目录路径try {// 1,创建本地文件下载路径File localFile = new File(localFilePath);if (!localFile.exists()) {localFile.mkdirs();}// 2,判断文件是否已经存在,如果存在,则先删除该文件File fi = new File(localFilePath + fileName);if (fi.exists()) {fi.delete();}// 3,转移到FTP服务器目录至指定的目录下ftpClient.changeWorkingDirectory(new String(ftpFilePath.getBytes(encoding), "iso-8859-1"));// 获取文件列表boolean isFileExist = false;FTPFile[] fs = ftpClient.listFiles();for (FTPFile ff : fs) {if (ff.getName().equals(fileName)) {File localFile1 = new File(localFilePath + "/" + fileName);is = new FileOutputStream(localFile1);ftpClient.retrieveFile(ff.getName(), is);isFileExist = true;break;}}if (!isFileExist) {log.error("文件" + fileName + "不存在");return result;}message = "下载文件: " + fileName + " 到目录: " + localFilePath + " 成功!";log.info(message);result = true;} catch (IOException e) {message = "下载文件: " + fileName + " 到目录: " + localFilePath + " 失败!";log.info(message);result = false;} finally {try {if (is != null) {is.close();}} catch (IOException e) {throw new RuntimeException("下载ftp文件OutputStream关闭失败!", e);}if (ftpClient.isConnected()) {try {ftpClient.disconnect();} catch (IOException e) {throw new RuntimeException("与ftp主机断开连接失败!", e);}}}} else {result = false;}return result;}

  • 多个文件下载
    /** * 方法 downloadFiles * * @param localFilePath 本地存放下载文件的路径 * @param files         ftp上的待下载的文件名称列表 * @param ftpFilePath   远程文件路径 * @return */public boolean downloadFiles(String localFilePath, String[] files, String ftpFilePath) {boolean result = false;String message = "";OutputStream is = null;String fileName = null;if (ftpClient != null) {try {// 转移到FTP服务器目录至指定的目录下ftpClient.changeWorkingDirectory(new String(ftpFilePath.getBytes(encoding), "iso-8859-1"));for (String str : files) {fileName = str;log.info("正在下载文件:" + fileName + ",请等待...");// 1,创建本地文件下载路径File localFile = new File(localFilePath);if (!localFile.exists()) {localFile.mkdirs();}// 2,判断文件是否已经存在,如果存在,则先删除该文件File fi = new File(localFilePath + fileName);if (fi.exists()) {fi.delete();}boolean isFileExist = false;// 获取文件列表FTPFile[] fs = ftpClient.listFiles();for (FTPFile ff : fs) {if (ff.getName().equals(fileName)) {File localFile1 = new File(localFilePath + "/" + fileName);is = new FileOutputStream(localFile1);ftpClient.retrieveFile(ff.getName(), is);isFileExist = true;break;}}if (!isFileExist) {log.error("文件" + fileName + "不存在");return result;}message = "下载文件: " + fileName + " 到目录: " + localFilePath + " 成功!";log.info(message);}result = true;} catch (IOException e) {message = "下载文件: " + fileName + " 到目录: " + localFilePath + " 失败!";log.error(message);result = false;} finally {try {if (is != null) {is.close();}} catch (IOException e) {throw new RuntimeException("下载ftp文件OutputStream关闭失败!", e);}if (ftpClient.isConnected()) {try {ftpClient.disconnect();} catch (IOException e) {throw new RuntimeException("与ftp主机断开连接失败!", e);}}}}return result;}

  • 单个文件上传(IO流形式)
    /** * 方法 uploadFile * * @param is          上传文件流 * @param fileName    ftp上的待上传的文件名 * @param ftpFilePath 远程文件路径 * @return */public boolean uploadFile(InputStream is, String fileName, String ftpFilePath) {boolean result = false;String message = "";if (ftpClient != null) {log.info("正在上传文件:" + fileName + ",请等待...");try {// 转移工作目录至指定目录下boolean change = ftpClient.changeWorkingDirectory(ftpFilePath);if (!change) {// 文件路径不存在this.makeDirectorys(ftpFilePath);}result = ftpClient.storeFile(new String(fileName.getBytes(encoding), "iso-8859-1"), is);if (!result) {log.error("上传文件失败!");return false;}message = "上传文件: " + fileName + " 到目录: " + ftpFilePath + " 成功!";log.info(message);result = true;} catch (IOException e) {message = "上传文件: " + fileName + " 到目录: " + ftpFilePath + " 失败!";log.error(message, e);result = false;} finally {try {if (is != null) {is.close();}} catch (IOException e) {throw new RuntimeException("上传ftp文件InputStream关闭失败!", e);}}}return result;}

  • 获取单个文件文件流
    /** * 方法 getFileInputStream 获取文件流 * * @param fileName      ftp上的待下载的文件名 * @param ftpFilePath   ftp远程文件路径 * @return */public InputStream getFileInputStream(String ftpFilePath,String fileName) {boolean result = false;InputStream is = null;try {result = ftpClient.changeWorkingDirectory(new String(ftpFilePath.getBytes(encoding), "iso-8859-1"));if (!result) {logger.error("切换路径到:"+ftpFilePath+"失败,请检查路径是否存在!");return null;}is = ftpClient.retrieveFileStream(fileName);return is;} catch (IOException e) {throw new RuntimeException("从文件路径"+ftpFilePath+"读取文件: " + fileName +  "失败!", e);}finally {try {//获取流成功情况下,手动告诉ftp,io流处理完成if(is != null){ftpClient.completePendingCommand();}} catch (IOException e) {throw new RuntimeException("执行ftpClient.completePendingCommand()失败", e);}}}

  • 复制文件到ftp新路径
     /**  * 复制文件.  *   * @param fileName   文件名称 * @param sourceFtpFilePath 源文件存放位置 * @param targetFtpFilePath  目标位置 */  public boolean copyFile(String fileName, String sourceFtpFilePath, String targetFtpFilePath)  {      ByteArrayInputStream in = null;      ByteArrayOutputStream fos = new ByteArrayOutputStream();     boolean result =false;    logger.info("从原路径"+sourceFtpFilePath+ "复制文件"+fileName+"到"+targetFtpFilePath+"开始");    try {  // 转移工作目录至指定目录下boolean change = ftpClient.changeWorkingDirectory(sourceFtpFilePath);if (!change) {// 文件路径不存在logger.error("原文件存放路径" + sourceFtpFilePath + "不存在");return result;}// 获取文件列表boolean isFileExist = false;FTPFile[] fs = ftpClient.listFiles();for (FTPFile ff : fs) {if (ff.getName().equals(fileName)) {ftpClient.retrieveFile(ff.getName(), fos);isFileExist = true;break;}}if (!isFileExist) {logger.error("文件" + fileName + "不存在");return result;}         in = new ByteArrayInputStream(fos.toByteArray());         // 返回根路径        returnRootDirectory();        // 切换到目标路径存放文件        change =  ftpClient.changeWorkingDirectory(targetFtpFilePath);          if (!change) {        // 文件路径不存在创建路径this.makeDirectorys(targetFtpFilePath);}        ftpClient.storeFile(new String(fileName.getBytes(encoding), "iso-8859-1"), in);          logger.info("从原路径"+sourceFtpFilePath+ "复制文件"+fileName+"到"+targetFtpFilePath+"成功");        return true;    }catch(Exception e){    throw new RuntimeException("从原路径"+sourceFtpFilePath+ "复制文件"+fileName+"到"+targetFtpFilePath+"失败。失败原因为:", e);    }finally {      try {if (in != null) {in.close();}} catch (IOException e) {throw new RuntimeException("复制ftp文件ByteArrayInputStream关闭失败!", e);}try {if (fos != null) {fos.close();}} catch (IOException e) {throw new RuntimeException("复制ftp文件ByteArrayOutputStream关闭失败!", e);}    }  } 

  • 递归创建路径(如/XXX/XXX/XXX)
    /** * 递归创建远程服务器目录 * * @param ftpFilePath 远程服务器文件绝对路径 * @return 目录创建是否成功 */public boolean makeDirectorys(String ftpFilePath) {boolean result = true;String directory = ftpFilePath.substring(0, ftpFilePath.lastIndexOf("/") + 1);try {if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory.getBytes(encoding), "iso-8859-1"))) {// 如果远程目录不存在,则递归创建远程服务器目录int start = 0;int end = 0;if (directory.startsWith("/")) {start = 1;} else {start = 0;}end = directory.indexOf("/", start);while (true) {String subDirectory = new String(ftpFilePath.substring(start, end).getBytes(encoding), "iso-8859-1");if (!ftpClient.changeWorkingDirectory(subDirectory)) {if (ftpClient.makeDirectory(subDirectory)) {ftpClient.changeWorkingDirectory(subDirectory);} else {logger.error("创建目录失败");return false;}}start = end + 1;end = directory.indexOf("/", start);// 检查所有目录是否创建完毕if (end <= start) {break;}}} else {logger.info("文件夹已经存在,不需要重新创建");}} catch (Exception e) {throw new RuntimeException( "创建文件夹过程出错", e);}return result;}

  • 获取ftp路径下文件列表
    /** * 获取文件列表(按时间倒序输出) * * @param ftpFilePath 远程文件路径 * @return */public List<FtpFileVo> getFtpFiles(String ftpFilePath) {List<FtpFileVo> list = new ArrayList<FtpFileVo>();try {// 转移到FTP服务器目录至指定的目录下    booleanresult = ftpClient.changeWorkingDirectory(new String(ftpFilePath.getBytes(encoding), "iso-8859-1"));if (!result) {log.error("切换路径到:"+ftpFilePath+"失败,请检查路径是否存在!");return list;}log.info("正在获取文件夹:" + ftpFilePath + "下文件列表,请等待...");FTPFile[] fs = ftpClient.listFiles();for (FTPFile ff : fs) {// 如果不是文件的类型,跳过if (!ff.getRawListing().startsWith("-")) {continue;}FtpFileVo vo = new FtpFileVo();vo.setFileName(ff.getName());vo.setLastModifyDate(ff.getTimestamp().getTime());vo.setSize(ff.getSize() / 1024);vo.setFilePath(ftpFilePath);list.add(vo);}// 按照时间倒序排序Collections.sort(list);log.info("获取文件路径下文件列表成功");return list;} catch (IOException e) {throw new RuntimeException( "获取文件列表过程出错", e);}}
    本功能需要使用vo辅助实现
    import java.util.Date;public class FtpFileVo implements Comparable<FtpFileVo> {private Date LastModifyDate;// 单位为kbprivate long size;private String fileName;private String filePath;public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public String getFilePath() {return filePath;}public void setFilePath(String filePath) {this.filePath = filePath;}public Date getLastModifyDate() {return LastModifyDate;}public void setLastModifyDate(Date lastModifyDate) {LastModifyDate = lastModifyDate;}public long getSize() {return size;}public void setSize(long size) {this.size = size;}public int compareTo(FtpFileVo stu) {return stu.getLastModifyDate().compareTo(this.LastModifyDate);}}

三:其他说明

  • Appache FTP下文件上传会是覆盖操作,所以上传前一定要考虑好是否备份
  • Appache FTP获取IO流方法,必须在Finally方法中执行以下方法,因为ftp不会自动放开本次流的操作,其余操作无法正常进行
    ftpClient.completePendingCommand();

四:结束

本文主要是进行FTP常用方法罗列,其中涉及到的方法中有部分已经在finally中进行连接断开,这部分内容可以根据实际需要进行,如多个操作在同一个流程中,就没有必要每次都连接,之后断开又连接,可以一次操作结束后再断开连接。






0 0
原创粉丝点击