java上传文件到FTP服务器

欢迎来到小生的博客,各种工具类,常用知识点、技巧持续更新中。。。。。。。
感谢大家点赞关注,希望大家能够给小生更多的支持。
祝您阅读愉快!
有任何疑问可以加小生QQ群咨询:107680366

前段时间,项目中使用到了上传文件到FTP服务器,再此略作整理,形成一个util工具,方便日后使用。
项目代码已上传至github:https://github.com/hack-feng/ftpdemo.git
点击直接前往

其中部分生成规则可以根据实际业务进行修改,删除

首先定义一个FTP服务器和上传文件的基础信息
封装一个FtpBean.java实体类

public class FtpBean {
	/**
	 * 部分信息如果传空的话,默认赋值,根据业务需求修改
	 */
	//FTP服务器地址
	private String address;
	//FTP服务器端口号
	private String port;
    //FTP服务器用户名
	private String username;
	//FTP服务器密码
	private String password;
	//上传文件名称
	private String fileName;
	//基本路径
	private String basepath;
	//文件输入流
	private InputStream inputStream;
	//保存文件方式  默认:1-覆盖;2-文件名称后面+(递增数据) 
	private Integer saveFileType;
	//省略get,set方法,详情可查询github上的源码

创建FTP上传工具类 FtpUtil.java:

public class FtpUtil {
	
	public static boolean uploadFile(FtpBean ftpBean) {
		
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(ftpBean.getAddress(), Integer.valueOf(ftpBean.getPort()));// 连接FTP服务器
			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
			ftp.login(ftpBean.getUsername(), ftpBean.getPassword());// 登录
			reply = ftp.getReplyCode();
			
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			
			String tempPath = ftpBean.getBasepath();
			String fileName = ftpBean.getFileName();
			if (!ftp.changeWorkingDirectory(ftpBean.getBasepath())) {
				//判断目录是否存在,如果目录不存在创建目录,目录存在则跳转到此目录下
				String []tempPathList = tempPath.split("/");
				for (String dir : tempPathList) {
					if(dir != null && dir != ""){
						if (!ftp.changeWorkingDirectory(dir)) {
							if (!ftp.makeDirectory(dir)) {
								return result;
							} else {
								ftp.changeWorkingDirectory(dir);
							}
						}
					}
				}
			}
			
			//保存文件方式  默认:1-覆盖;2-文件名称后面+(递增数据) 
			if(ftpBean.getSaveFileType() == 2){
				FTPFile[]file = ftp.listFiles();
				Integer i = 1;
				//采用递归,文件名重复自动加(i)
				fileName = aaa(file, i, fileName, fileName);
			}
			//设置上传文件的类型为二进制类型
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			//设置模式很重要
			ftp.enterLocalActiveMode();
			//上传文件
			result = ftp.storeFile(fileName, ftpBean.getInputStream());
			if(!result){
				return result;
			}

			ftpBean.getInputStream().close();
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	
	//递归重命名去重复
	public static String aaa(FTPFile[] file, int i, String fileName, String nameFlag){
		boolean isOk = true;
		for (FTPFile file2 : file) {
			String flag = file2.getName();
			if(nameFlag.equals(flag)){
				String []fileNames = fileName.split("\\.");
				if(fileNames.length > 0){
					nameFlag = "";
				}
				for (int j = 0; j < fileNames.length; j++) {
					if(j == fileNames.length-1){
						nameFlag = nameFlag+"("+i+")."+fileNames[j];
					}else if(j == fileNames.length-2){
						nameFlag = nameFlag + fileNames[j];
					}else{
						nameFlag = nameFlag + fileNames[j] + ".";
					}
				}
				i += 1;
				isOk = false;
			}else{
				isOk = true;
			}
		}
		
		if(isOk == false){
			nameFlag = aaa(file, i, fileName, nameFlag);
		}
		return nameFlag;
	}
}

生成上传路径规则工具类 GenerateDirUtil.java:

public class GenerateDirUtil {
	
	public static enum Type{
		DEFAULT,
		FILETYPE
	}

	/**
	 *  <p>
	 *  type为DEFAULT或者type为null时:获取原文件所在路径,直接在FTP创建此路径保存
	 *  type为FILETYPE时:则根据文件类型创建目录
	 *  </p>
	 *  @method_Name    : fileDirectory
	 *  @author         : Maple
	 *  @creation       : 2019年3月15日 下午1:59:31 
	 *  @param file
	 *  @return
	 */
	public static String fileDirectory(File file, Type type){
		if(Type.FILETYPE.equals(type)){
			String resDir = "/";
			resDir = new MimetypesFileTypeMap().getContentType(file);
			resDir.replace('\\', '/');
			return "/"+resDir;
		}else{
			String resDir = "/";
			resDir = file.getParent();
			return resDir;
		}
	}
}

创建测试用例FtpDemo.java:

public class FtpDemo {
	
	public static void main(String[] args){
		
		//获取本地需要上传的文件,此处只用作测试
		File file = new File("D:\\test\\ftp.txt");
		
		if(file.isFile() && file.exists()){
			
			//设置FTP上传的基本信息,可直接初始化数据
			FtpBean ftp = new FtpBean();
			
			//自动生成路径,默认取源文件路径,为FILETYPE时,取文件类型做路径
			//如使用自己的路径,直接ftp.setBasepath赋值即可
			String basepath = GenerateDirUtil.fileDirectory(file, GenerateDirUtil.Type.FILETYPE);
			ftp.setBasepath(basepath);
			
			/**
			 * 文件名生成方式
			 * 1、自己命名			ftp.setBasepath("aaaa.txt");
			 * 2、取文件原名字		ftp.setBasepath(file.getName());
			 * 3、根据时间戳自动生成	
			 */
			SimpleDateFormat sdfms = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			String date = sdfms.format(System.currentTimeMillis());
			//添加三位自动生成的数字,防止重复
			int i=(int)(Math.random()*900)+100; 
			String fileName = date + i +".txt";
			ftp.setFileName(fileName);
			
			//测试命名重复递增
			fileName = "aaa.txt";
			
			try{
				//将文件转换成一个输入流
				InputStream in = new FileInputStream(file);
				ftp.setInputStream(in);
				//传入文件名称,和文件输入流,上传至FTP服务器
				boolean isOk = FtpUtil.uploadFile(ftp);
				if(isOk){
					System.out.println("文件上传成功");
				}else{
					System.out.println("文件上传失败");
				}
				in.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}else{
			System.out.println("文件不存在");
		}
	}
}

待上传的文件截图:
在这里插入图片描述
上传至FTP服务器后的截图,分别用按时间戳命名和固定不重复命名两种方法实现: