1、與FTP服務器建立連接
/** * 初始化客戶端並完成對服務端的連接 * @param server 服務端地址 * @param port 端口號 * @param username 用戶名 * @param password 密碼 * @param path 遠程路徑 值可以為空 * @throws SocketException * @throws IOException */ public static FTPClient connectServer(String server, int port, String username,String password, String path) { if(null == path){ path = ""; } try { FTPClient ftp = new FTPClient(); //下面四行代碼必須要,而且不能改變編碼格式,否則不能正確下載中文文件 // 如果使用serv-u發布ftp站點,則需要勾掉“高級選項”中的“對所有已收發的路徑和文件名使用UTF-8編碼” ftp.setControlEncoding("GBK"); FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); conf.setServerLanguageCode("zh"); ftp.configure(conf); ftp.connect(server, port); ftp.setDataTimeout(120000); // 判斷ftp是否存在 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) { ftp.disconnect(); // 如果不存在,斷開ftp連接 log.warn(server + " FTP拒絕連接"); } // 登陸ftp boolean flag = ftp.login(username, password); if (flag) { log.info("FTP登錄成功。"); }else { log.error("FTP登錄失敗。"); } // 根據輸入的路徑,切換工作目錄。這樣ftp端的路徑就可以使用相對路徑了 if (path.length() != 0) { if (path != null && !"".equals(path.trim())) { // 對路徑按照‘/’進行切割,一層一層的進入 String[] pathes = path.split("/"); for (String onepath : pathes) { if (onepath == null || "".equals(onepath.trim())) { continue; } if (!ftp.changeWorkingDirectory(onepath)) { ftp.makeDirectory(onepath); boolean flagDir = ftp.changeWorkingDirectory(onepath); log.info(ftp.printWorkingDirectory()); if (flagDir) { log.info("成功連接ftp目錄:" + ftp.printWorkingDirectory()); } else { log.error("未能連接ftp目錄:" + ftp.printWorkingDirectory()); } } } } } return ftp; }catch(SocketException e){ e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } }
2、返回目錄下的所有文件(包括文件夾)
/** * 返回給定目錄下的所有文件(包括文件夾) * @param path * @return FTPFile組成的集合 * @throws IOException */ public static List<String> getFileList(FTPClient ftp,String path) throws IOException { ftp.changeWorkingDirectory(path);//切換對應路徑下 log.info("FTP當前目錄:"+ftp.printWorkingDirectory()); FTPFile[] ftpFiles = ftp.listFiles(); // ftpFiles.length返回當前目錄下的文件數 List retList = new ArrayList(); if (ftpFiles == null || ftpFiles.length == 0) { return retList; } for (int i = 0; i < ftpFiles.length; i++) { FTPFile ftpFile = ftpFiles[i]; // if (ftpFile.isFile()) { // 判斷是否為文件,這樣返回的就是所有的文件名 // retList.add(ftpFile.getName()); // } retList.add(ftpFile.getName()); } return retList; }
3、獲取指定路徑下的所有文件(不管多少文件夾下)
/** * 遞歸遍歷文件夾以及子文件夾的文件 * 獲取指定路徑下的所有文件(不管多少文件夾下) * @param pathName * @param filePathList * @throws IOException */ public static void getFileListRecursion(FTPClient ftp,String pathName, List<String> filePathList) throws IOException { if(null == pathName){ pathName = "/"; }else{ pathName = pathName.replace("\\", "/"); } if(!pathName.startsWith("/")){ pathName ="/"+pathName; } if(!pathName.endsWith("/")){ pathName = pathName + "/"; } ftp.changeWorkingDirectory(pathName); FTPFile[] files = ftp.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { log.info("得到文件:" + files[i].getName()); log.info("--------------"); filePathList.add(ftp.printWorkingDirectory()+"/"+files[i].getName()); } else if (files[i].isDirectory()) { getFileListRecursion(ftp,pathName + files[i].getName() + "/", filePathList); } } }
4、刪除指定目錄(遞歸)
/** * 刪除指定目錄下的所有文件 * @param ftp * @param pathname * @return */ public static boolean removeAll(FTPClient ftp, String pathname) { try { ftp.removeDirectory(pathname); FTPFile[] files = ftp.listFiles(pathname); for (FTPFile f : files) { if (f.isDirectory()) { removeAll(ftp,pathname + "/" + f.getName()); boolean isDelDir = ftp.removeDirectory(pathname); log.info("FTP目錄是否已刪除>>"+isDelDir); } if (f.isFile()) { boolean isDelFile = ftp.deleteFile(pathname + "/" + f.getName()); ftp.removeDirectory(pathname); log.info("FTP文件是否已刪除>>"+isDelFile); } } } catch (IOException e) { e.printStackTrace(); return false; } return true; }
5、上傳文件,並重命名
/** * 上傳文件,並重命名. * @param filePathName 上傳的文件,包含目錄的文件名 * @param newName 新的文件名 * @return 上傳結果,是否成功. * @throws IOException */ public static boolean uploadFile(FTPClient ftp,String filePathName, String newName) throws IOException { boolean flag = false; InputStream iStream = null; try { log.info("ftp new file name : "+newName); ftp.setControlEncoding("GBK"); iStream = new FileInputStream(filePathName); ftp.setFileType(FTPClient.BINARY_FILE_TYPE); //將當前數據連接模式設置為PASSIVE_LOCAL_DATA_CONNECTION_MODE,即:被動模式 ftp.enterLocalPassiveMode(); //將流寫到服務器 ftp.storeFile(new String(filePathName.getBytes("GBK"),"iso-8859-1"),iStream); flag = ftp.storeFile(newName, iStream); } catch (IOException e) { flag = false; return flag; } finally { if (iStream != null) { iStream.close(); } } return flag; }
6、從ftp上下載文件到本地
/** * 從ftp上下載文件到本地 * @param ftpClient:ftp連接 * @param remoteFilepath:ftp服務器端路徑 * @param localFilePath:本地路徑 * @return 是否下載成功 */ public static boolean downloadFileFromFtp(FTPClient ftpClient,String remoteFilepath,String localFilePath){ boolean flag = false; try { //判斷本地文件是否已經存在,如果已經存在,則無需下載 //FTPClient ftpClient = FtpUtil.connectServer(ftp); File localFile = new File(localFilePath); if (!localFile.exists()) { InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath); if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath); }else { if (localFile.length() == 0) { log.info("文件大小為0,即將為您重新下載!"); localFile.delete(); InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath); if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath); // 將文件流轉化為本地文件 }else{ log.info("本地文件已存在......."); flag = true; } } FtpUtil.closeServer(ftpClient); return flag; } catch (Exception e) { flag = false; log.error("從FTP下載文件到本地失敗..."); log.error(e); e.printStackTrace(); return flag; } } /** * 將文件流轉化為本地文件 * @param inputStream * @param localFilePath * @return boolean * @throws IOException */ public static boolean inputStreamToFile(InputStream inputStream,String localFilePath) throws IOException { File newDir = new File(localFilePath.replace("\\", "/").substring(0, localFilePath.lastIndexOf("\\"))); if (!newDir.exists()) newDir.mkdirs(); FileOutputStream fs= new FileOutputStream(localFilePath); try { /*FileChannel fc= ((FileInputStream) inputStream).getChannel(); log.info("文件大小:"+fc.size());*/ int bytesum = 0; int byteread = 0; byte[] buffer = new byte[1024]; long startTime = System.currentTimeMillis(); while ((byteread = inputStream.read(buffer)) != -1) { bytesum += byteread; // 字節數 文件大小 fs.write(buffer, 0, byteread); } fs.flush(); long endTime = System.currentTimeMillis(); log.info("將文件流轉化為本地文件耗時/毫秒:"+(endTime-startTime)); return true; } catch (Exception e) { log.error("將文件流轉化為本地文件失敗",e); return false; }finally{ fs.close(); } }
7、獲取下一級目錄列表 文件+文件夾(返回list<PathVo>)
/** * 獲取下一級目錄列表 文件+文件夾(返回list<PathVo>) * @param ftp * @param pathName * @return * @throws IOException */ public static List<PathVo> getNextDirectory(FTPClient ftp,String pathName) throws IOException { log.info("Ftp中pathName:"+pathName); List<PathVo> filePathList = new ArrayList<PathVo>(); if(null == pathName) pathName = "/"; else pathName = pathName.replace("\\", "/"); if(!pathName.startsWith("/")) pathName ="/"+pathName; if(!pathName.endsWith("/")) pathName = pathName + "/"; boolean flag = ftp.changeWorkingDirectory(pathName); if (!flag) { log.info("重定位失敗。"); return filePathList; } log.info("目錄切換"+ftp.printWorkingDirectory()); //ftp.enterLocalActiveMode();//主動模式,默認 ftp.enterLocalPassiveMode();//被動模式 //ftp.configure(new FTPClientConfig("dist.dgp.util.fileZillaPlugin.UnixFTPEntryParser"));//FileZilla安裝FTP時使用 String[] list = ftp.listNames(); System.out.println(list.length); FTPFile[] files = ftp.listFiles(); if (files == null || files.length == 0) { ftp.changeToParentDirectory(); return filePathList; } log.info("文件長度:"+files.length); for (int i = 0; i < files.length; i++) { PathVo vo = new PathVo(); if (files[i].isFile()) { vo.setType("file"); vo.setFullPath(pathName+files[i].getName()); vo.setSize(formatSize(files[i].getSize())); vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis())); vo.setLabel(files[i].getName()); vo.setExtension(files[i].getName().substring(files[i].getName().lastIndexOf(".")+1)); vo.setChildren(null); filePathList.add(vo); } else if (files[i].isDirectory()) { vo.setType("folder"); vo.setFullPath(pathName+files[i].getName()); vo.setLabel(files[i].getName()); vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis())); vo.setChildren(getNextDirectory(ftp,pathName + files[i].getName() + "/")); filePathList.add(vo); } } log.info("filePathList.size():"+filePathList.size()); return filePathList; }
8、獲取文件最后編輯時間
/** * 獲取文件最后編輯時間 * @param filename * @return */ public static String getFileLastModified(long timeInMillis) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm"); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(timeInMillis); return sdf.format(cal.getTime()); }
9、其他
FTPClient ftp = new FTPClient(); ftp.logout(); // 關閉ftp連接 ftp.setFileType(fileType); // 設置ftp的文件傳輸類型 ftp.changeWorkingDirectory(path); // 改變ftp的工作目錄 ftp.removeDirectory(path); // 刪除一個FTP服務器上的目錄(如果為空) ftp.deleteFile(pathName); // 刪除文件