一.首先登錄ftp服務器:命令行 lftp user@ip 上傳:put 下載: get
二. 關於FTP傳輸模式與傳輸的方式
眾所周知,FTP傳輸有兩種工作模式,Active Mode和Passive Mode(主動模式和被動模式),簡單描述連接過程如下:
1.主動模式的連接過程是:客戶端向服務器的FTP端口(默認是21)發送連接請求,服務器接受連接,建立一條命令鏈路。當需要傳送數據時, 客戶端在命令鏈路上用PORT命令告訴服務器:“我打開了***端口,你過來連接我”。於是服務器從20端口向客戶端的***端口發送連接請求,建立一條數據鏈路來傳送數據。
2.被動模式的連接過程是:客戶端向服務器的FTP端口(默認是21)發送連接請求,服務器接受連接,建立一條命令鏈路。當需要傳送數據時, 服務器在命令鏈路上用PASV命令告訴客戶端:“我打開了***端口,你過來連接我”。於是客戶端向服務器的***端口發送連接請求,建立一條數據鏈路來傳送數據。
了解模式的目的,是為了了解端口。使用 FTP 傳輸時,至少會使用到兩個 Port 來建立連接通道:
-
一個為指令通道(Command Channel),默認使用 Port 21 建立,用來傳輸 FTP 指令,例如:列出清單(LIST)、變更目錄(CWD)、取得目前的目錄(PWD)、......等。
-
另一個為數據通道(DATA Channel),默認使用 Port 20,但是會因 FTP Client 選擇使用的模式不同而有所不同.
1.ASCII傳輸方式
假定用戶正在拷貝的文件包含的簡單ASCII碼文本,如果在遠程機器上運行的不是UNIX,當文件傳輸時ftp通常會自動地調整文件的內容以便於把文件解釋成另外那台計算機存儲文本文件的格式。
但是常常有這樣的情況,用戶正在傳輸的文件包含的不是文本文件,它們可能是程序,數據庫,字處理文件或者壓縮文件。在拷貝任何非文本文件之前,用binary 命令告訴ftp逐字拷貝。
2.二進制傳輸模式
在二進制傳輸中,保存文件的位序,以便原始和拷貝的是逐位一一對應的。即使目的地機器上包含位序列的文件是沒意義的。例如,macintosh以二進制方式傳送可執行
文件到Windows系統,在對方系統上,此文件不能執行。
如在ASCII方式下傳輸二進制文件,即使不需要也仍會轉譯。這會損壞數據。(ASCII方式一般假設每一字符的第一有效位無意義,因為ASCII字符組合不使用它。如果
傳輸二進制文件,所有的位都是重要的
三.不多做解釋,上傳一段FTPS的代碼
public class FtpsUtil { private static final Logger LOGGER = LoggerFactory.getLogger(FtpsUtil.class); /** * 暴露的方法 */ public boolean uploadFile(InputStream in, String dirName, String remoteFileName, String adder, int port, String userName, String userPassword) { FTPSClient ftpClient = null; try { LOGGER.info("uploadFile addr:{},port:{},userName:{},userPassword:{}", adder, port, userName, userPassword); ftpClient = ftpConnection(adder, port, userName, userPassword); makeDirectory(ftpClient, dirName); ftpClient.changeWorkingDirectory(dirName); boolean isUploadSuccess = ftpPut(ftpClient, remoteFileName, in); if (isUploadSuccess) { return true; } } catch (Exception e) { LOGGER.error("上傳文件失敗了。。upload file Exception:", e); } finally { ftpClose(ftpClient); } return false; } private FTPSClient ftpConnection(String adder, int port, String userName, String passWord) { FTPSClient ftpClient = null; try { ftpClient = new FTPSClient(false); ftpClient.connect(adder, port); ftpClient.login(userName, passWord); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); ftpClient.execPROT("P"); ftpClient.enterLocalPassiveMode(); LOGGER.info("ftpconnection success"); } catch (Exception e) { LOGGER.error("ftpconnection EXception:", e); } return ftpClient; } private void makeDirectory(FTPSClient ftpClient, String dirName) { try { ftpClient.makeDirectory(dirName); LOGGER.info("創建文件夾成功:{}", dirName); } catch (Exception e) { LOGGER.error("目錄已經存在,無需創建"); } } private boolean ftpPut(FTPSClient ftpClient, String filename, InputStream in) throws IOException { try { boolean result = ftpClient.storeFile(filename, in); if (result) { LOGGER.info("upload file success"); } return result; } catch (Exception ex) { LOGGER.error("上傳文件發生異常了。。。", ex); return false; } finally { if (in != null) { in.close(); } } } private boolean ftpClose(FTPSClient ftpClient) { try { if (ftpClient != null) { ftpClient.logout(); ftpClient.disconnect(); } LOGGER.info("ftpClose success"); } catch (Exception e) { LOGGER.error("ftpclose Exception:", e); return false; } return true; } }