package lixj.ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.SocketException; import java.util.logging.Logger; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; public class FTPUtils { private static FTPUtils instance = null; private static FTPClient ftpClient = null; //本地文件目錄所在磁盤路徑 private static final String DISC_PATH = "D:/server"; // 本地字符編碼 private static final String LOCAL_CHARSET = "GBK"; // FTP協議規定文件名編碼為iso-8859-1 private static final String SERVER_CHARSET = "ISO-8859-1"; //FTP服務器IP private String server = "172.20.10.105"; //FTP服務器端口 private int port = 21; //FTP用戶名 private String userName = "lixj"; //FTP用戶密碼 private String userPassword = "123456"; //日志工具 private static Logger logger = Logger.getLogger(FTPUtils.class.getName()); public static FTPUtils getInstance(){ if(instance == null){ instance = new FTPUtils(); } ftpClient = new FTPClient(); return instance; } /** * 連接FTP服務器 * @return */ private boolean connect(){ boolean stat = false; try { if(ftpClient.isConnected()) return true; ftpClient.connect(server, port); stat = true; } catch (SocketException e) { stat = false; e.printStackTrace(); } catch (IOException e) { stat = false; e.printStackTrace(); } return stat; } /** * 打開FTP服務器 * @return */ public boolean open(){ if(!connect()){ return false; } boolean stat = false; try { stat = ftpClient.login(userName, userPassword); // 檢測連接是否成功 int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { close(); stat = false; } } catch (IOException e) { e.printStackTrace(); stat = false; } return stat; } /** * 關閉FTP服務器 */ public void close(){ if(ftpClient != null && ftpClient.isConnected()){ try { ftpClient.logout(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { ftpClient.disconnect(); ftpClient = null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 同步文件 * @param relativeFilePath 文件相對路徑 * @return succ = true | fail = false */ public boolean syncFile(String relativeFilePath) { if (relativeFilePath == null || "".equals(relativeFilePath.trim())) { logger.info("文件相對路徑不能為空!"); return false; } if (new File(DISC_PATH + relativeFilePath).exists()) { //本地存在文件,執行文件上傳操作 logger.info("上傳文件【"+relativeFilePath+"】"); return uploadFile(DISC_PATH, relativeFilePath); } else {//本地不存在文件,到FTP服務器下載文件 logger.info("下載文件【"+relativeFilePath+"】"); return downloadFile(DISC_PATH, relativeFilePath); } } /** * 上傳文件 * @param discPath 文件所在磁盤路徑 * @param relativePath 文件所在相對路徑 * @return succ = true | fail = false */ public boolean uploadFile(String discPath, String relativePath){ if (discPath == null || "".equals(discPath.trim())) { logger.info("discPath 文件所在磁盤路徑不能為空!"); return false; } if (relativePath == null || "".equals(relativePath.trim())) { logger.info("relativePath 文件相對路徑不能為空!"); return false; } String dir = relativePath.substring(0, relativePath.lastIndexOf("/")); String filename = relativePath.substring(relativePath.lastIndexOf("/")+1); logger.info("文件相對目錄="+dir); logger.info("文件名="+filename); return uploadFile(dir, filename, discPath + relativePath); } /** * 上傳文件到FTP服務器 * @param ftpPath FTP-目錄 * @param ftpFileName FTP-文件名 * @param filePath 本地文件完整路徑 * @return succ = true | fail = false */ public boolean uploadFile(String ftpPath, String ftpFileName, String filePath){ FileInputStream input = null; try { mkFtpDirs(ftpPath); ftpClient.changeWorkingDirectory(changeCode(ftpPath)); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding(LOCAL_CHARSET); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); input = new FileInputStream(new File(filePath)); boolean result = ftpClient.storeFile(changeCode(ftpFileName), input); if (result) { logger.info("上傳成功!"); } else { logger.info("上傳失敗!"); } } catch (IOException e) { e.printStackTrace(); } finally { if (input != null) { try { input.close(); input = null; } catch (IOException e) { // TODO Auto-generated catch block } } } return false; } /** * 下載文件 * @param discPath 文件所在磁盤路徑 * @param relativePath 文件所在相對路徑 * @return */ public boolean downloadFile(String discPath, String relativePath){ if (discPath == null || "".equals(discPath.trim())) { logger.info("discPath 文件所在磁盤路徑不能為空!"); return false; } if (relativePath == null || "".equals(relativePath.trim())) { logger.info("relativePath 文件路徑不能為空!"); return false; } String dir = relativePath.substring(0, relativePath.lastIndexOf("/")); String filename = relativePath.substring(relativePath.lastIndexOf("/")+1); logger.info("文件相對目錄="+dir); logger.info("文件名="+filename); return downloadFile(dir, filename, discPath + dir); } /** * 下載文件路徑 * @param ftpPath * @param ftpFileName * @param localPath * @return */ public boolean downloadFile(String ftpPath, String ftpFileName, String localPath) { FileOutputStream fos = null ; try { File localDirFile = new File(localPath); if (!localDirFile.exists()) { localDirFile.mkdirs(); } fos = new FileOutputStream(new File(localPath, ftpFileName)); ftpClient.enterLocalPassiveMode(); ftpClient.changeWorkingDirectory(changeCode(ftpPath)) ; boolean result = ftpClient.retrieveFile(changeCode(ftpFileName), fos); if (result) { logger.info("下載成功!"); } else { logger.info("下載失敗!"); } return result; } catch (Exception e) { e.printStackTrace(); } finally { if (fos!=null) { try { fos.close() ; fos = null ; } catch (Exception e2) { } } } return false; } /*** * 創建FTP服務器多個層級目錄 * @param dir e.g:/目錄1/目錄2/目錄3 * @return */ public boolean mkFtpDirs(String dir){ boolean stat = false; String[] dirs = dir.split("/"); if(dirs.length == 0){ return stat; } try { ftpClient.changeToParentDirectory(); for(String dirss : dirs){ ftpClient.makeDirectory(changeCode(dirss)); ftpClient.changeWorkingDirectory(changeCode(dirss)); } ftpClient.changeToParentDirectory(); stat = true; } catch (IOException e) { e.printStackTrace(); stat = false; } return stat; } /** * 刪除文件 * @param filePathName * @return */ public boolean removeFtpFile(String filePathName){ boolean stat = false; try{ stat = ftpClient.deleteFile(changeCode(filePathName)); }catch(Exception e){ e.printStackTrace(); stat = false; } return stat; } /** * 轉換文件或目錄字符編碼 * @param fileOrDirName 文件名或目錄名 * @return 轉換后的字符串 */ private String changeCode(String fileOrDirName) { try { return new String(fileOrDirName.getBytes(LOCAL_CHARSET), SERVER_CHARSET); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } public static void main(String[] args) { FTPUtils ftp = FTPUtils.getInstance(); ftp.open(); ftp.syncFile("/upload/測試目錄/建設項目技術規范書V3.5(1).docx"); ftp.close(); } }