使用commons-net來下載文件(僅做記錄)
阿新 • • 發佈:2018-06-18
datatime repl eve time ole pri 讀取數據 mod ets 使用 commons-net-3.6.jar
public class ApacheFtpUtil { private Logger log = LoggerFactory.getLogger(ApacheFtpUtil.class); private String host; private String username; private String password; // 控制端口 private int port = 21; // 秒數 private int defaultTimeoutSecond = 60; private int connectTimeoutSecond = 30; private int dataTimeoutSecond = 30; // 秒 private int controlKeepAliveTimeout = 120; private boolean isTextMode = false; private String tranEncoding = "GB2312"; private FTPClient client; public ApacheFtpUtil(String host, String username, String password) { this(host, username, password, 21, 0); } public ApacheFtpUtil(String host, String username, String password, int port) { this(host, username, password, port, 0); } public ApacheFtpUtil(String host, String username, String password, int port, int security) { this.host = host; this.port = port; this.username = username; this.password = password; } public void initClint() throws Exception { // FTPSClient client = new FTPClient(); // 每大約2分鐘發一次noop,防止大文件傳輸導致的控制連接中斷 client.setControlKeepAliveTimeout(controlKeepAliveTimeout); // client.setListHiddenFiles(listHiddenFiles); // FTPClientConfig config = new // FTPClientConfig(FTPClientConfig.SYST_NT); // config.setServerLanguageCode("zh"); // config.setUnparseableEntries(saveUnparseable); // config.setDefaultDateFormatStr(defaultDateFormat); // config.setRecentDateFormatStr(recentDateFormat); // client.configure(config); // 設置默認超時 client.setDefaultTimeout(defaultTimeoutSecond * 1000); // 連接超時 // client.setConnectTimeout(connectTimeoutSecond * 1000); // 設置數據超時 // client.setDataTimeout(dataTimeoutSecond * 1000); /* * socket超時 設置一個命令執行後最大等待Server反饋的時間. 如果對方連接狀態60秒沒有收到數據的話強制斷開客戶端 */ // client.setSoTimeout(60 * 1000); // client.setBufferSize(1024); // 連接到遠程的FTP服務器. try { client.connect(this.host, this.port); } catch (Exception e) { this.destory(); log.error("連接服務器失敗,host:{}, port:{}", this.host, this.port); throw e; } int reply = client.getReplyCode(); // 獲得返回的代碼,來判斷連接狀態 if (!FTPReply.isPositiveCompletion(reply)) { this.destory(); // 連接錯誤 throw new Exception("Can‘t Connect to :" + host); } // 登錄 boolean flag = client.login(this.username, this.password); if (flag == false) { this.destory(); throw new Exception("Invalid user/password"); } try { if (FTPReply.isPositiveCompletion(client.sendCommand("OPTS UTF8", "ON"))) { // 開啟服務器對UTF-8的支持,如果服務器支持就用UTF-8編碼,否則就使用本地編碼 tranEncoding = "UTF-8"; log.debug("FTP Server allow UTF8 encoding"); } } catch (Exception e) { log.error("ftp server opts utf8 error,{}", e.getMessage()); } log.info("use encoding {}", tranEncoding); client.setControlEncoding(tranEncoding); // 中文支持 // 設置傳送模式 if (isTextMode) { client.setFileType(FTP.ASCII_FILE_TYPE); } else { client.setFileType(FTP.BINARY_FILE_TYPE); } /* * PORT中文稱為主動模式,工作的原理: * FTP客戶端連接到FTP服務器的21端口,發送用戶名和密碼登錄,登錄成功後要list列表或者讀取數據時, * 客戶端隨機開放一個端口(1024以上),發送 PORT命令到FTP服務器,告訴服務器客戶端采用主動模式並開放端口; * FTP服務器收到PORT主動模式命令和端口號後,通過服務器的20端口和客戶端開放的端口連接,發送數據. * 主動模式需要客戶端必須開放端口給服務器,很多客戶端都是在防火墻內,開放端口給FTP服務器訪問比較困難。 */ // client.enterLocalActiveMode(); //主動模式 /* * PASV是Passive的縮寫,中文成為被動模式. * 工作原理:FTP客戶端連接到FTP服務器的21端口,發送用戶名和密碼登錄,登錄成功後要list列表或者讀取數據時, * 發送PASV命令到FTP服務器, 服務器在本地隨機開放一個端口(1024以上),然後把開放的端口告訴客戶端, * 客戶端再連接到服務器開放的端口進行數據傳輸. 被動模式只需要服務器端開放端口給客戶端連接就行了。 */ client.enterLocalPassiveMode(); // client.setUseEPSVwithIPv4(useEpsvWithIPv4); log.debug("==========初始化FTP連接成功==========="); } public void destory() { if (client == null) { return; } try { client.logout(); } catch (IOException e) { e.printStackTrace(); } try { client.disconnect(); } catch (IOException e) { e.printStackTrace(); } client = null; } public void changeRemoteDir(String newPath) throws RuntimeException { // 切換路徑[相對路徑和絕對路徑都可] if (StringUtils.isBlank(newPath)) { return; } try { boolean flag = client.changeWorkingDirectory(new String(newPath.getBytes(tranEncoding), "ISO-8859-1")); log.debug("change working directory to {}, status:{}", newPath, flag); } catch (IOException e) { throw new RuntimeException("切換路徑失敗:" + newPath + "; " + e.getMessage()); } } /** * 下載文件 */ public void download(String remoteFile, String localOutFile) throws RuntimeException { FileOutputStream outstream = null; // 下載文件 try { log.debug("開始下載文件 {}", remoteFile); outstream = new FileOutputStream(new File(localOutFile)); /* * 這個方法的意思就是每次數據連接之前,ftp client告訴ftp server開通一個端口來傳輸數據. 因為ftp * server可能每次開啟不同的端口來傳輸數據,但是在linux上,由於安全限制,可能某些端口沒有開啟,所以就出現阻塞 */ client.enterLocalPassiveMode(); client.setFileType(FTP.BINARY_FILE_TYPE); /* * FTP協議裏面,規定文件名編碼為iso-8859-1,所以目錄名或文件名需要轉碼 retrieveFile的第一個參數需要是 * ISO-8859-1 編碼 */ client.retrieveFile(new String(remoteFile.getBytes(tranEncoding), "ISO-8859-1"), outstream); } catch (IOException e) { throw new RuntimeException("下載文件失敗:" + remoteFile + "; " + e.getMessage()); } finally { if (outstream != null) { try { outstream.flush(); outstream.close(); } catch (IOException e) { } } } log.debug("下載文件 {} 完成", remoteFile); } }
使用commons-net來下載文件(僅做記錄)