最近在做一个上传下载对账单功能,其中部分用到了ftpclient这个类,分享出来。顺便看看自己写的有没有缺点。
1.首先你需要在http://mvnrepository.com/下载或者引入:
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.3</version><!--版本号请随意--></dependency>然后复制下面的类到你的工程中(代码中包含了连接时间的监控):
package com.wz.ftpclient;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.SocketException;import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPClientConfig;import org.apache.commons.net.ftp.FTPFile;import org.apache.commons.net.ftp.FTPReply;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class FtpClient { private static Logger log = LoggerFactory.getLogger(FtpClient.class); private String host; private int port; private String username; private String passWord; private FTPClient ftp = new FTPClient(); /** * @param host ip地址 * @param port 端口号 * @param username 用户名 * @param password 密码 */ public FtpClient(String host, int port, String username, String password) { this.host = host; this.port = port; this.username = username; this.password = password; //有必要进行设置 FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX); conf.setServerLanguageCode("zh"); //解决文件名的中文乱码问题 ftp.setControlEncoding("GBK"); //编码问题请自己调试一下 ftp.configure(conf); } /** * 连接ftp服务器 * @return */ private boolean connectFtp() { boolean flag = false; int reply; try { long startLogin = System.currentTimeMillis(); ftp.connect(host, port);// 连接ftp服务器 log.info("连接:" + host + ":" + port); ftp.login(username, password);// 登录 log.info("登录:" + username + password); reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); log.info("登陆失败"); return false; } flag = true; long endLogin = System.currentTimeMillis(); log.info("登录成功,登录耗时:" + (endLogin - startLogin) + "ms"); log.info("开启被动模式"); ftp.enterLocalPassiveMode(); ftp.setFileType(FTP.BINARY_FILE_TYPE); ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE); } catch (IOException e) { log.error("连接异常,请检查地址和端口", e); } return flag; } /** * 登出 * @return */ private boolean logOut() { long logOutTime = System.currentTimeMillis(); boolean flag = false; try { if (ftp != null) flag = ftp.logout(); } catch (IOException e) { log.error("登出异常", e); } finally{ try { ftp.disconnect(); } catch (IOException e) { log.error("disconnect异常", e); } } long endLogOutTime = System.currentTimeMillis(); log.info("登出耗时:" + (endLogOutTime - logOutTime) + "ms"); return flag; } /** * 上传文件 * @param path ftp服务器的文件路径 * @param filename 保存文件名 * @param inputStream 文件流 * @return */ private boolean uploadFile(String path, String filename, InputStream inputStream) { boolean flag = false; if (connectFtp()) { try { log.info("Remote system is " + ftp.getSystemType()); if (!makeDirectory(path)){ //创建路径,你必须先创建/a/b,再创建/a/b/c log.info("创建目录【" + path + "】失败"); return false; } else ftp.changeWorkingDirectory(path); ftp.enterLocalPassiveMode(); ftp.setFileType(FTPClient.BINARY_FILE_TYPE); flag = ftp.storeFile(filename, inputStream); if (flag == true) { log.info("上传成功"); } else { log.info("上传失败"); } } catch (SocketException e) { log.error("Socket异常", e); } catch (IOException e) { log.error("io异常", e); } finally { try { if (inputStream != null) inputStream.close(); } catch (IOException e) { log.error("io异常", e); } logOut(); } } return flag; } private boolean makeDirectory(String path) throws IOException{ String[] paths = getEntirelyPath(path); for (int j = 0; j < paths.length; j++) { if (!ftp.changeWorkingDirectory(paths[j])){ if (!ftp.makeDirectory(paths[j])){ log.info("创建目录" + paths[j] + "失败"); return false; } } } return true; } /** * 获得完全的路径集合 * 比如 参数 path=/a/b/c/d/ 得到 String[] = '/','/a/','/a/b/','/a/b/c/','/a/b/c/d/' * @param path * @return */ private static String[] getEntirelyPath(String path){ String[] pathArray = path.split("/"); String[] paths = new String[pathArray.length]; int j = 0; StringBuilder p = new StringBuilder(); for (int i = 0; i < pathArray.length; i++) { paths[j] = p.append(pathArray[i]).append("/").toString(); j++; } return paths; } /** * 上传文件 * @param path ftp服务器的文件路径 * @param filename 文件名 * @param sourcePath 要上传的文件路径 * @return */ public boolean uploadFile(String path, String filename, String sourcePath) { boolean flag = false; File file = new File(sourcePath); if (file.exists() && file.isFile()) { try { FileInputStream fis = new FileInputStream(file); flag = uploadFile(path, filename, fis); } catch (FileNotFoundException e) { log.error("File异常", e); } } else { log.error("文件不存在或者该文件是文件夹"); } return flag; } /** * * @param downloadPath 保存到本地的路径 * @param remotePath 远程路径 * @param remoteFilenames 远程文件集合 * @return */ public boolean downloadFile(String downloadPath, String remotePath, String[] remoteFilenames) { boolean downloadFlag = false; if (connectFtp()) { long startDownloadTime = System.currentTimeMillis(); try { if (ftp.changeWorkingDirectory(remotePath)) { log.info("当前目录:" + ftp.printWorkingDirectory()); long singleDownTime = 0; long writeFileTime = 0; long startMatchTime = System.currentTimeMillis(); for (String remoteFilename : remoteFilenames) { long startDownloadFile = System.currentTimeMillis(); InputStream inputStream = ftp.retrieveFileStream(remoteFilename); long endDownloadFile = System.currentTimeMillis(); log.info("下载文件" + remoteFilename + "耗时:" + (endDownloadFile - startDownloadFile) + "ms"); singleDownTime = endDownloadFile - startDownloadFile; if (inputStream == null) { log.info("无法下载文件:" + remoteFilename); continue; } else { log.info("下载的文件是:" + remoteFilename); } long startWriteFileTolocal = System.currentTimeMillis(); OutputStream output = new FileOutputStream(new File(downloadPath + remoteFilename)); byte[] bytes = new byte[1024]; int i = -1; try { while ((i = inputStream.read(bytes)) != -1) { output.write(bytes, 0, i); } output.flush(); downloadFlag = true; } catch (IOException e) { log.error("IO异常", e); } finally { inputStream.close(); ftp.completePendingCommand(); output.close(); } long endWriteFileTolocal = System.currentTimeMillis(); writeFileTime += (endWriteFileTolocal - startWriteFileTolocal); } long endMatchTime = System.currentTimeMillis(); log.info("文件匹配耗时:" + (endMatchTime - startMatchTime - singleDownTime - writeFileTime)+ "ms"); log.info("写入文件耗时:" + writeFileTime + "ms"); } } catch (IOException e) { log.error("切换工作目录报错!", e); } long endDownloadTime = System.currentTimeMillis(); log.info("下载所有文件加匹配耗时:" + (endDownloadTime - startDownloadTime) + "ms"); logOut(); } return downloadFlag; } /** * 罗列某个路径下的所有文件和子路径 * @param path * @return * @throws IOException */ public FTPFile[] listFiles(String path) throws IOException{ if (connectFtp()) { try { log.info("Remote system is " + ftp.getSystemType()); log.info("查看路径:" + path); return ftp.listFiles(path); } catch (Exception e) { log.error("查询ftp目录异常", e); } finally { logOut(); } } return new FTPFile[0]; } /** * 罗列某两个路径下的所有文件和子路径 * 可以改造成-不定参类型 String... path * @param pathA * @param pathB * @return * @throws IOException */ public FTPFile[] listFiles(String pathA, String pathB) throws IOException{ if (connectFtp()) { try { log.info("Remote system is " + ftp.getSystemType()); log.info("查看路径:" + pathA); FTPFile[] fileA = ftp.listFiles(pathA); FTPFile[] fileB = ftp.listFiles(pathB); FTPFile[] totalFiles = new FTPFile[fileA.length+fileB.length]; System.arraycopy(fileA, 0, totalFiles, 0, fileA.length); System.arraycopy(fileB, 0, totalFiles, fileA.length, fileB.length); return totalFiles; } catch (Exception e) { log.error("查询ftp目录异常", e); } finally { logOut(); } } return new FTPFile[0]; } public static void main(String[] args) { FtpClient ftpClient = new FtpClient("127.0.0.1", 21, "a", "b"); //上传 ftpClient.uploadFile("/a/b/c/d/", "1.txt", "D://tmp//1.txt"); //下载 ftpClient.downloadFile("D://tmp//", "/a/b/c/d/", new String[]{"1.txt","2.txt"}); }}亲测可用,如有需要,你直接copy即可。如果有什么问题,你可以评论或私信我。
新闻热点
疑难解答