Appache Ftp使用(二)

1 篇文章 0 订阅

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服务器目录至指定的目录下
    		    boolean	result = 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;
    	// 单位为kb
    	private 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值