下面就来写下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; } }