一、FTP介绍

FTP是File Transfer Protocol(文件传输协议)的英文简称,即文件协议。用于Internet上的控制文件的双向传输。同时,它是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有的应用程序都遵守同一种协议以传输文件。在FTP的使用中,用户经常遇到两个概念:下载(Download)和上次(Upload)。下载文件就是从远程主机拷贝文件至自己的计算机上;删除文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向远程主机上传、下载文件(摘自百度百科)。

二、准备工作

1、在服务器安装FTP服务


FTP服务需要下FileZilla_Server服务安装程序,大家可以在网上搜索,也可以通过我的资源下载

2、编写Java连接FTP源码

三、实现步骤

1、编写FTP-Config.properties配置属性文件

FTP_IP=localhost
FTP_PORT=21
FTP_USER=wangjunwei
FTP_PASSWORD=wangjunwei
FTP_PATH=/FTP
FTP_DRIVELETTER=E:

2、编写FTPUtil读取FTP配置属性文件

/**
	 * FTP服务地址
	 */
	private static String FTP_IP;
	/**
	 * FTP端口号
	 */
	private static Integer FTP_PORT;
	/**
	 * FTP用户名
	 */
	private static String FTP_USER;
	/**
	 * FTP密码
	 */
	private static String FTP_PASSWORD;
	/**

	 * FTP根路径
	 */
	private static String FTP_PATH;
	/**
	 * 映射盘符
	 */
	private static String FTP_DRIVELETTER;
	static{
		try {
			Properties properties = new Properties();
			InputStream inputStream = FtpUtil.class.getResourceAsStream("/FTP-Config.properties");
			properties.load(inputStream);
			FTP_IP = properties.getProperty("FTP_IP");
			FTP_PORT = Integer.valueOf(properties.getProperty("FTP_PORT"));
			FTP_USER = properties.getProperty("FTP_USER");
			FTP_PASSWORD = properties.getProperty("FTP_PASSWORD");
			FTP_PATH = properties.getProperty("FTP_PATH");
			FTP_DRIVELETTER = properties.getProperty("FTP_DRIVELETTER");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

3、连接(登录)FTP服务端获取授权

private static FTPClient ftpClient;

	public static FTPClient connectionFTPServer() {
		ftpClient = new FTPClient();
		try {
			ftpClient.connect(FtpUtil.getFTP_IP(), FtpUtil.getFTP_PORT());
			ftpClient.login(FtpUtil.getFTP_USER(), FtpUtil.getFTP_PASSWORD());
			if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
				logger.info("==============未连接到FTP,用户名或密码错误=================");
				ftpClient.disconnect();
			} else {
				logger.info("==============连接到FTP成功=================");
			}
		} catch (SocketException e) {
			e.printStackTrace();
			logger.info("==============FTP的IP地址错误==============");
		} catch (IOException e) {
			e.printStackTrace();
			logger.info("==============FTP的端口错误==============");
		}
		return ftpClient;
	}

4、编写文件上传、下载相关方法

/**
	 * 切换到父目录
	 * 
	 * @return 切换结果 true:成功, false:失败
	 */
	private static boolean changeToParentDir() {
		if (!ftpClient.isConnected()) {
			return false;
		}
		try {
			return ftpClient.changeToParentDirectory();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 改变当前目录到指定目录
	 * 
	 * @param dir
	 *            目的目录
	 * @return 切换结果 true:成功,false:失败
	 */
	private static boolean cd(String dir) {
		if (!ftpClient.isConnected()) {
			return false;
		}
		try {
			return ftpClient.changeWorkingDirectory(dir);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 获取目录下所有的文件名称
	 * 
	 * @param filePath
	 *            指定的目录
	 * @return 文件列表,或者null
	 */
	private static FTPFile[] getFileList(String filePath) {
		if (!ftpClient.isConnected()) {
			return null;
		}
		try {
			return ftpClient.listFiles(filePath);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 切换工作目录
	 * 
	 * @param ftpPath
	 *            目的目录
	 * @return 切换结果
	 */
	public static boolean changeDir(String ftpPath) {
		if (!ftpClient.isConnected()) {
			return false;
		}
		try {
			// 将路径中的斜杠统一
			char[] chars = ftpPath.toCharArray();
			StringBuffer sbStr = new StringBuffer(256);
			for (int i = 0; i < chars.length; i++) {
				if ('\\' == chars[i]) {
					sbStr.append('/');
				} else {
					sbStr.append(chars[i]);
				}
			}
			ftpPath = sbStr.toString();
			if (ftpPath.indexOf('/') == -1) {
				// 只有一层目录
				ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(), "iso-8859-1"));
			} else {
				// 多层目录循环创建
				String[] paths = ftpPath.split("/");
				for (int i = 0; i < paths.length; i++) {
					ftpClient.changeWorkingDirectory(new String(paths[i].getBytes(), "iso-8859-1"));
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 循环创建目录,并且创建完目录后,设置工作目录为当前创建的目录下
	 * 
	 * @param ftpPath
	 *            需要创建的目录
	 * @return
	 */
	public static boolean mkDir(String ftpPath) {
		if (!ftpClient.isConnected()) {
			return false;
		}
		try {
			// 将路径中的斜杠统一
			char[] chars = ftpPath.toCharArray();
			StringBuffer sbStr = new StringBuffer(256);
			for (int i = 0; i < chars.length; i++) {
				if ('\\' == chars[i]) {
					sbStr.append('/');
				} else {
					sbStr.append(chars[i]);
				}
			}
			ftpPath = sbStr.toString();
			if (ftpPath.indexOf('/') == -1) {
				// 只有一层目录
				ftpClient.makeDirectory(new String(ftpPath.getBytes(), "iso-8859-1"));
				ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(), "iso-8859-1"));
			} else {
				// 多层目录循环创建
				String[] paths = ftpPath.split("/");
				for (int i = 0; i < paths.length; i++) {
					ftpClient.makeDirectory(new String(paths[i].getBytes(), "iso-8859-1"));
					ftpClient.changeWorkingDirectory(new String(paths[i].getBytes(), "iso-8859-1"));
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 上传单个文件
	 * 
	 * @param inputStream
	 *            单个文件流对象
	 * @param newFileName
	 *            新文件名
	 * @param folder
	 *            自定义保存的文件夹
	 * @return 上传结果
	 */
	public static boolean uploadSingleAttachment(File file, String newFileName, String folder) {
		FtpUtil.connectionFTPServer();
		if (!ftpClient.isConnected()) {
			logger.info("==============FTP服务已断开==============");
			return false;
		}
		boolean result = false;
		if (ftpClient != null) {
			FileInputStream fileInputStream = null;
			try {
				fileInputStream = new FileInputStream(file);
				if(StringUtils.isNotEmpty(folder)){
					FtpUtil.mkDir(folder);
				}
				ftpClient.setBufferSize(100000);
				ftpClient.setControlEncoding("utf-8");
				ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				result = ftpClient.storeFile(new String(newFileName.getBytes(), "iso-8859-1"), fileInputStream);
			} catch (Exception e) {
				FtpUtil.close();
				e.printStackTrace();
				return false;
			} finally {
				try {
					if (ftpClient.isConnected()) {
						FtpUtil.close();
					}
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	/**
	 * 上传多个文件
	 * 
	 * @param inputStreams
	 *            多文件流对象数组
	 * @param newFileNames
	 *            多文件名数组(与流对象数组一一对应)
	 * @param folder
	 *            自定义保存的文件夹
	 * @return 上传结果
	 */
	public static String[] uploadBatchAttachment(File[] files , String[] newFileNames, String folder) {
		String[] filesSaveUrls = new String[files.length];
		FtpUtil.connectionFTPServer();
		if (!ftpClient.isConnected()) {
			logger.info("==============FTP服务已断开==============");
			return null;
		}
		if (ftpClient != null) {
			FileInputStream fileInputStream = null;
			try {
				if(StringUtils.isNotEmpty(folder)){
					FtpUtil.mkDir(folder);
				}
				for (int i = 0; i < files.length; i++) {
					filesSaveUrls[i] = FtpUtil.FTP_PATH;
					fileInputStream = new FileInputStream(files[i]);
					if(StringUtils.isNotEmpty(folder)){
						filesSaveUrls[i] += "/"+folder;
					}
					ftpClient.setBufferSize(100000);
					ftpClient.setControlEncoding("utf-8");
					ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
					ftpClient.storeFile(new String(newFileNames[i].getBytes(), "iso-8859-1"), fileInputStream);
					filesSaveUrls[i] += "/"+newFileNames[i];
				}
			} catch (Exception e) {
				FtpUtil.close();
				e.printStackTrace();
				return null;
			} finally {
				try {
					if (ftpClient.isConnected()) {
						FtpUtil.close();
					}
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return filesSaveUrls;
	}
	/**
	 * 上传单个文件
	 * 
	 * @param inputStreams
	 *            多文件流对象数组
	 * @param newFileNames
	 *            多文件名数组(与流对象数组一一对应)
	 * @param folder
	 *            自定义保存的文件夹
	 * @return 上传结果
	 */
	public static String uploadSingleAttachment(MultipartFile multipartFile, String newFileName, String folder) {
		String filesSaveUrl = null;
		FtpUtil.connectionFTPServer();
		if (!ftpClient.isConnected()) {
			logger.info("==============FTP服务已断开==============");
			return null;
		}
		if (ftpClient != null) {
			try {
				if(StringUtils.isNotEmpty(folder)){
					FtpUtil.mkDir(folder);
				}
				filesSaveUrl = FtpUtil.FTP_PATH;
				if(StringUtils.isNotEmpty(folder)){
					filesSaveUrl += "/"+folder;
				}
				ftpClient.setBufferSize(100000);
				ftpClient.setControlEncoding("utf-8");
				ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				ftpClient.storeFile(new String(newFileName.getBytes(), "iso-8859-1"), multipartFile.getInputStream());
				filesSaveUrl += "/"+newFileName;
			} catch (Exception e) {
				FtpUtil.close();
				e.printStackTrace();
				return null;
			} finally {
				if (ftpClient.isConnected()) {
					FtpUtil.close();
				}
			}
		}
		return filesSaveUrl;
	}
	/**
	 * 上传多个文件
	 * 
	 * @param inputStreams
	 *            多文件流对象数组
	 * @param newFileNames
	 *            多文件名数组(与流对象数组一一对应)
	 * @param folder
	 *            自定义保存的文件夹
	 * @return 上传结果
	 */
	public static String[] uploadBatchAttachment(MultipartFile[] multipartFiles , String[] newFileNames, String folder) {
		String[] filesSaveUrls = new String[multipartFiles.length];
		FtpUtil.connectionFTPServer();
		if (!ftpClient.isConnected()) {
			logger.info("==============FTP服务已断开==============");
			return null;
		}
		if (ftpClient != null) {
			InputStream inputStream = null;
			try {
				if(StringUtils.isNotEmpty(folder)){
					FtpUtil.mkDir(folder);
				}
				for (int i = 0; i < multipartFiles.length; i++) {
					filesSaveUrls[i] = FtpUtil.FTP_PATH;
					inputStream = multipartFiles[i].getInputStream();
					if(StringUtils.isNotEmpty(folder)){
						filesSaveUrls[i] += "/"+folder;
					}
					ftpClient.setBufferSize(100000);
					ftpClient.setControlEncoding("utf-8");
					ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
					ftpClient.storeFile(new String(newFileNames[i].getBytes(), "iso-8859-1"), inputStream);
					filesSaveUrls[i] += "/"+newFileNames[i];
				}
			} catch (Exception e) {
				FtpUtil.close();
				e.printStackTrace();
				return null;
			} finally {
				try {
					if (ftpClient.isConnected()) {
						FtpUtil.close();
					}
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return filesSaveUrls;
	}

	/**
	 * 根据文件url下载文件
	 * 
	 * @param path 被下载文件url
	 * @return 文件流对象
	 * @throws IOException
	 */
	public static final InputStream downLoadFile(String path,String filaName){
		FtpUtil.connectionFTPServer();
		if (!ftpClient.isConnected()) {
			logger.info("==============FTP服务已断开==============");
			return null;
		}
		 ftpClient.enterLocalPassiveMode();
		 FtpUtil.changeDir(path);
		 try {
			return ftpClient.retrieveFileStream(filaName);
		} catch (IOException e) {
			logger.info("==============获取文件异常==============");
			e.printStackTrace();
			return null;
		}finally{
			if (ftpClient.isConnected()) {
				FtpUtil.close();
			}
		}
	}
	 
	/**
	 * 返回FTP目录下的文件列表
	 * 
	 * @param pathName
	 * @return
	 */
	public static String[] getFileNameList(String pathName) {
		if (!ftpClient.isConnected()) {
			return null;
		}
		try {
			return ftpClient.listNames(pathName);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 删除FTP上的文件
	 * 
	 * @param ftpDirAndFileName
	 *            路径开头不能加/,比如应该是test/filename1
	 * @return
	 */
	public static boolean deleteFile(String ftpDirAndFileName) {
		if (!ftpClient.isConnected()) {
			FtpUtil.connectionFTPServer();
		}
		try {
			return ftpClient.deleteFile(ftpDirAndFileName);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 删除FTP目录
	 * 
	 * @param ftpDirectory
	 * @return
	 */
	public static boolean deleteDirectory(String ftpDirectory) {
		if (!ftpClient.isConnected()) {
			return false;
		}
		try {
			return ftpClient.removeDirectory(ftpDirectory);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 关闭链接
	 */
	public static void close() {
		try {
			if (ftpClient != null && ftpClient.isConnected()) {
				ftpClient.disconnect();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}