FTP上传文件功能

ftp上传功能是很多的应用软件都必备的一个基础功能,特别是CMS系统,这个是必须的功能:
下面就来写下ftp上传主要的功能代码吧;

第一步:准备工作:需要的jar包是:commons net 3.3.jar,commons.io.jar,这个可以在网络上找到的。版本不一定是这个的。把下载的jar包加入到maven的pom.xml或者放到lib目录下面。
commons net 3.3.jar下载地址: http://download.csdn.net/download/hdh1988/5808981

第二步:把ftp上传功能所有的功能都写,封装成一个封装类:
主要的功能有上传,下载,删除等:


package bianliang.com;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;







public class FtpUtil {
	private String ip;
	private int port;
	private String username;
	private String password;
	private boolean isPrepared = false;

	protected FTPClient ftpClient = null;
  /**
   * ftpConfig配置的的顺序是:ftp上传的ip#端口#登录用户名#密码
   * @param ftpConfig
   * @throws FtpException
   */
	public FtpUtil(String ftpConfig) throws FtpException {
		String[] configs = ftpConfig.split("#");
		if (configs.length != 4) {
			throw new FtpException("FTP连接参数格式错误");
		} else {
			this.ip = configs[0];
			this.port = Integer.valueOf(configs[1]);
			this.username = configs[2];
			this.password = configs[3];
		}
	}

	/**
	 * 登录到FTP Server
	 * 
	 * @return
	 * @throws FtpException
	 */
	public boolean connect() throws FtpException{
		boolean result = false;
		try {
			ftpClient = new FTPClient();
			ftpClient.setControlEncoding("UTF-8");
			ftpClient.connect(ip, port);
			result = ftpClient.login(username, password);
			if (result) {
				ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				ftpClient.setBufferSize(1024 * 2);
				ftpClient.setDataTimeout(3000);
				this.isPrepared = true;
				return true;
			} else {
				ftpClient.disconnect();
				throw new FtpException( "用户名或密码错误");
			}
		} catch (IOException e) {
			ftpClient = null;
			throw new FtpException(e.getMessage());
		}
	}

	/**
	 * 退出登录并断开连接
	 * 
	 * @return
	 * @throws FtpException
	 */
	public boolean disconnect() throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		try {
			this.ftpClient.disconnect();
		} catch (IOException e) {
			throw new FtpException(e.getMessage());
		}
		return true;
	}

	/**
	 * 上传文件
	 * 
	 * @param localFile 上传本地文件的文件名
	 * @param remoteFileName
	 * @throws FtpException
	 * @return
	 */
	public boolean uploadFile(String localFileName, String remoteFileName) throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		checkAndCreateDirectory(remoteFileName);
		File localFile = new File(localFileName);
		boolean result = false;
		FileInputStream inputStream = null;
		try {
			ftpClient.enterLocalPassiveMode();
			inputStream = new FileInputStream(localFile);
			result = ftpClient.storeFile(remoteFileName, inputStream);
			int code = ftpClient.getReplyCode();
			if (FTPReply.isPositiveCompletion(code)) {
				Logger.info("FTP工具", "上传文件至FTP", "FtpUtil", "method", "uploadFile", "上传文件成功:" + this.ip + remoteFileName);
			} else {
				throw new FtpException("向FTP上传文件出错:" + this.ip + remoteFileName + "Reply Code:" + code);
			}
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		} finally {
			if (inputStream != null)
				try {
					inputStream.close();
				} catch (IOException e) {
					throw new FtpException( e.getMessage());
				}
		}
		try {
			ftpClient.pwd();// 没有实际作用的指令,用来避免有时候上传到FTP的文件大小变为0的问题
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		} 
		return result;
	}
	
	/**
	 * 上传文件夹(包含子文件夹)
	 * 
	 * @param localFolderPath
	 * @param remoteFolderPath
	 * @return
	 * @throws FtpException
	 */
	public boolean uploadFolder(String localFolderPath, String remoteFolderPath) throws FtpException{
		boolean result = false;
		for (String fileName : getLocalFileNameList(localFolderPath)) {
			String relativePath = fileName.substring(localFolderPath.length()).replaceAll("\\\\", "/");
			result = uploadFile(fileName, remoteFolderPath + relativePath);
		}
		return result;
	}
	

	/**
	 * 将String中的内容保存至远程指定文件
	 * 
	 * @param uploadString
	 * @param remoteFileName
	 * @throws FtpException
	 * @return
	 */
	public boolean uploadString(String uploadString, String remoteFileName) throws FtpException{
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		boolean result = false;
		InputStream inputStream = null;
		try {
			inputStream = new ByteArrayInputStream(uploadString.getBytes("UTF-8"));
			checkAndCreateDirectory(remoteFileName);
			ftpClient.enterLocalPassiveMode();
			result = ftpClient.storeFile(remoteFileName, inputStream);
			int code = ftpClient.getReplyCode();
			if (FTPReply.isPositiveCompletion(code)) {
				logger.info(log, "FTP工具", "上传字符串至FTP", "FtpUtil", "method", "uploadString", "上传字符串成功:" + this.ip +remoteFileName);
			} else {
				throw new FtpException( "向FTP上传字符串出错:" + this.ip + remoteFileName + ",Reply Code:" + code);
			}
		} catch (Exception e) {
			throw new FtpException( e.getMessage());
		} finally {
			if (inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					throw new FtpException( e.getMessage());
				}
			}
		}
		try {
			ftpClient.pwd();// 没有实际作用的指令,用来避免有时候上传到FTP的文件大小变为0的问题
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		} 
		return result;
	}

	/**
	 * 从服务器下载文件
	 * 
	 * @param localFileName
	 * @param remoteFileName
	 * @throws FtpException
	 */
	public boolean downloadFile(String localFileName, String remoteFileName) throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		File fileDir = new File(localFileName);
		if (!fileDir.getParentFile().exists()) {
			fileDir.getParentFile().mkdirs();
		}
		BufferedOutputStream outputStream = null;
		boolean result = false;
		try {
			outputStream = new BufferedOutputStream(new FileOutputStream(localFileName));
			result = this.ftpClient.retrieveFile(remoteFileName, outputStream);
			if (result) {
				logger.info(log, "FTP工具", "从FTP下载文件", "FtpUtil", "method", "downloadFile", "从FTP下载文件成功:" + localFileName);
			} else {
				throw new FtpException( "从FTP下载文件出错:" + remoteFileName);
			}
		} catch (Exception e) {
			throw new FtpException( e.getMessage());
		} finally {
			if (outputStream != null) {
				try {
					outputStream.flush();
					outputStream.close();
				} catch (IOException e) {
					throw new FtpException( e.getMessage());
				}
			}
		}
		return result;
	}

	/**
	 * 从服务器文件获取String
	 * 
	 * @param remoteFileName
	 * @return String
	 * @throws FtpException
	 */
	public String downloadString(String remoteFileName) throws FtpException{
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		
		String result = null;		
		try {
		    
		    InputStream inputStream = ftpClient.retrieveFileStream(remoteFileName);
			
			if (inputStream != null) {
			    
			    result = IOUtils.toString(inputStream, "UTF-8");
	            inputStream.close();
	            ftpClient.completePendingCommand();
	            logger.info(log, "FTP工具", "从FTP获取String", "FtpUtil", "method", "downloadString", "从FTP获取String成功:" + this.ip + remoteFileName);	            
			
			} else {
			    throw new FtpException( "retrieveFileStream is null");
			}
				
		} catch (IOException e) {
		    
			throw new FtpException(e.getMessage());
			
		}
		
		logger.info(log, "FTP工具", "从FTP获取String", "FtpUtil", "method", "downloadString", "从FTP获取String结束:" + this.ip + remoteFileName);
		return result;
	}
	
	/**
	 * 获取远程路径下的所有文件名(选择性包括子文件夹)
	 * 
	 * @param remotePath
	 *            远程路径
	 * @param isAll
	 *            是否包含子文件夹
	 * @return List<String>
	 * @throws FtpException
	 */
	public List<String> getRemoteFileNameList(String remotePath, Boolean isAll) throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		FTPFile[] ftpFiles;
		List<String> retList = new ArrayList<String>();
		try {
			ftpFiles = ftpClient.listFiles(remotePath);
			if (ftpFiles == null || ftpFiles.length == 0) {
				return retList;
			}
			for (FTPFile ftpFile : ftpFiles) {
				if (ftpFile.isDirectory() && !ftpFile.getName().startsWith(".") && isAll) {
					String subPath = remotePath + "/" + ftpFile.getName();
					for (String fileName : getRemoteFileNameList(subPath, true)) {
						retList.add(fileName);
					}
				} else if (ftpFile.isFile()) {
					retList.add(remotePath + "/" + ftpFile.getName());
				}
			}
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		}
		return retList;
	}

	/**
	 * 下载远程路径下的所有文件(选择性包括子文件夹)
	 * 
	 * @param remotePath
	 *            远程地址
	 * @param isAll
	 *            是否包含子文件夹
	 * @param localPath
	 *            本地存放路径
	 * @return
	 * @throws FtpException
	 */
	public boolean downloadFolder(String remotePath, Boolean isAll, String localPath) throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		boolean result = false;
		List<String> fileNameList;
		fileNameList = getRemoteFileNameList(remotePath, isAll);
		for (String fileName : fileNameList) {
			String relativePath = fileName.substring(remotePath.length(), fileName.length());
			String localFileName = localPath + relativePath;
			result = downloadFile(localFileName, fileName);
		}
		return result;
	}

	/**
	 * 删除远程服务器上指定文件
	 * 
	 * @param remoteFileName
	 * @return
	 * @throws FtpException
	 */
	public boolean deleteFile(String remoteFileName) throws FtpException {
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		boolean result = false;
		try {
			result = this.ftpClient.deleteFile(remoteFileName);
			logger.info(log, "FTP工具", "从FTP删除文件", "FtpUtil", "method", "deleteFile", "从FTP删除文件成功:" + this.ip + remoteFileName);
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		}
		return result;
	}
	
	/**
	 * 删除远程服务器上指定文件夹(文件夹内一定要为空)
	 * 
	 * @param remoteFolderPath
	 * @throws FtpException
	 */
	public void deleteEmptyFolder(String remoteFolderPath) throws FtpException{
		if (!isPrepared) {
			throw new FtpException("对FTP操作前应先登录");
		}
		try {
			if (this.ftpClient.removeDirectory(remoteFolderPath)){
				logger.info(log, "FTP工具", "从FTP删除文件夹", "FtpUtil", "method", "deleteEmptyFolder", "从FTP删除文件夹成功:" + this.ip + remoteFolderPath);
			}else {
				throw new FtpException( "从FTP删除文件夹出错");
			}
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		}
	}
	
	/**
	 * 删除远程文件夹及其内的所有文件(包括子文件夹)
	 * 
	 * @param remoteFolderPath
	 * @throws FtpException
	 * @throws IOException
	 */
	public void deleteFolder(String remoteFolderPath) throws FtpException{
		if (!isPrepared) {
			throw new FtpException( "对FTP操作前应先登录");
		}
		FTPFile[] ftpFiles;
		try {
			ftpFiles = ftpClient.listFiles(remoteFolderPath);
			for (FTPFile ftpFile : ftpFiles) {
				if (ftpFile.isFile()) {
					deleteFile(remoteFolderPath + "/" + ftpFile.getName());
				}else if (ftpFile.isDirectory() && !ftpFile.getName().startsWith(".")){
					deleteFolder(remoteFolderPath + "/" + ftpFile.getName());
				}
			}
			deleteEmptyFolder(remoteFolderPath);
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		}
		
	}
	
	/**
	 * 检查远程路径是否存在,若不则递归创建文件夹
	 * 
	 * @param remotePath
	 * @throws FtpException
	 */
	private void checkAndCreateDirectory(String remotePath) throws FtpException{  
        String directory = remotePath.substring(0,remotePath.lastIndexOf("/")+1);  
        try {
			if(!directory.equalsIgnoreCase("/") &&! ftpClient.changeWorkingDirectory(directory)){  
			    int preLocation=0;  
			    int nextLocation = 0;  
			    if(directory.startsWith("/")) preLocation = 1;  
			    nextLocation = directory.indexOf("/",preLocation);  
			    while(nextLocation > preLocation){
			        String subDirectory = new String(remotePath.substring(preLocation,nextLocation));  
			        if(!ftpClient.changeWorkingDirectory(subDirectory)){  
			            if(ftpClient.makeDirectory(subDirectory)){  
			               ftpClient.changeWorkingDirectory(subDirectory);  
			            } 
			        }
			        preLocation = nextLocation + 1;  
			        nextLocation = directory.indexOf("/",preLocation);  
			    }  
			}
			 ftpClient.changeWorkingDirectory("/");
		} catch (IOException e) {
			throw new FtpException( e.getMessage());
		}
       
    }
	
	/**
	 * 获取本地文件夹下的所有文件名
	 * 
	 * @param localFolderPath
	 * @return
	 */
	public List<String> getLocalFileNameList(String localFolderPath) {
		File originalFile = new File(localFolderPath);
		File[] files = originalFile.listFiles();
		List<String> list = new ArrayList<String>();
		if (files == null || files.length == 0) {
			return list;
		}
		for (File file : files) {

			if (file.isDirectory()) {
				String subPath = localFolderPath + "/" + file.getName();
				for (String fileName : getLocalFileNameList(subPath)) {
					list.add(fileName);
				}
			} else if (file.isFile()) {
				list.add(file.getPath());
			}
		}
		return list;
	}
	
	/**
	 * ftp上传服务器的代码
	 * @param ftpFileLocaCfg 上传的文件配置,请看第一个方法
	 * @param filePath   上传的文件的路径地址
	 * @param fileName  上传的文件名称
	 * @return
	 */
	public boolean uploadFtpFile( String ftpFileLocaCfg, String filePath,String fileName){
		 boolean flag = false;
		 FileInputStream inputStream = null;
		 try {
		 //是否成功登录FTP服务器
		 int replyCode = ftpClient.getReplyCode();
		 //如果reply >= 200) && (reply < 300,表示没有保存成功
		 if(!FTPReply.isPositiveCompletion(replyCode)){
			 
		 return flag;
		 }
		 inputStream = new FileInputStream( new File(filePath));
		 ftpClient.enterLocalPassiveMode();
		 ftpClient.changeWorkingDirectory(ftpFileLocaCfg);
		 //保存文件
		 flag = ftpClient.storeFile(fileName, inputStream);
		 inputStream.close();
		 ftpClient.logout();
		 } catch (Exception e) {
		 e.printStackTrace();
		 } finally{
		 if(ftpClient.isConnected()){
		 try {
		 ftpClient.disconnect();
		 } catch (IOException e) {
		 e.printStackTrace();
		 }
		 }
		 }
		 return flag;
		 }
	
}





第三步:异常类配置


package bianliang.com;

public class FtpException  extends Exception{
	private static final long serialVersionUID = 3116679193767247127L;

	private String message;


	public FtpException( String message) {
		
		this.message=message;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

}





猜你喜欢

转载自lfc-jack.iteye.com/blog/2343027