Java连接FTP服务器并且实现对其文件的上传和下载
概述
? FTP是File Transfer Protocol(文件傳輸協議)的英文簡稱,而中文簡稱為“文傳協議”。FTP作為網絡共享文件的傳輸協議,在網絡應用軟件中具有廣泛的應用。FTP的目標是提高文件的共享性和可靠高效地傳送數據。在FTP的使用當中,用戶經常遇到兩個概念:"下載"(Download)和"上傳"(Upload)。本文就主要針對這兩個操作來進行說明(當然,也包括FTP服務器的連接和登錄等操作)。
?
版權說明
商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
本文作者:Q-WHai
發表日期: 2015年11月12日
本文鏈接:http://blog.csdn.net/lemon_tree12138/article/details/49777467
來源:CSDN
更多內容:分類 >>?Thinking In Java
?
筆者環境
? 系統環境:Windows 7(客戶端與服務器均是)
? 服務器:自建FTP服務器(關于FTP服務器的搭建,本文不作說明。網上都有.)
? 開發環境:Jdk 1.8
? 引入第三方庫:commons-net-2.2.jar(針對第一種方法)
?
一、基于第三方庫FtpClient的FTP服務器數據傳輸
? 由于是基于第三方庫,所以這里基本上沒有太多要說明的東西。就是導入第三方庫再調用即可,調用過程從下面的代碼可以參見。為了便于文章的完整性,這也是給出其程序結構圖吧。
圖-1 基于FtpClient的FTP網絡文件傳輸圖
?
1.FTP的連接及登錄
?
public static FtpClient connectFTP(String url, int port, String username, String password) {//創建ftpFtpClient ftp = null;try {//創建地址SocketAddress addr = new InetSocketAddress(url, port);//連接ftp = FtpClient.create();ftp.connect(addr);//登陸ftp.login(username, password.toCharArray());ftp.setBinaryType();} catch (FtpProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return ftp;}2.上傳文件到FTP服務器
?
public static void upload(String localFile, String ftpFile, FtpClient ftp) {OutputStream os = null;FileInputStream fis = null;try {// 將ftp文件加入輸出流中。輸出到ftp上os = ftp.putFileStream(ftpFile);File file = new File(localFile);// 創建一個緩沖區fis = new FileInputStream(file);byte[] bytes = new byte[1024];int c;while((c = fis.read(bytes)) != -1){os.write(bytes, 0, c);}System.out.println("upload success!!");} catch (FtpProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(os!=null) {os.close();}if(fis!=null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}?
3.從FTP服務器下載文件
?
public static void download(String localFile, String ftpFile, FtpClient ftp) {InputStream is = null;FileOutputStream fos = null;try {// 獲取ftp上的文件is = ftp.getFileStream(ftpFile);File file = new File(localFile);byte[] bytes = new byte[1024];int i;fos = new FileOutputStream(file);while((i = is.read(bytes)) != -1){fos.write(bytes, 0, i);}System.out.println("download success!!");} catch (FtpProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(fos!=null) {fos.close();}if(is!=null){is.close();}} catch (IOException e) {e.printStackTrace();}}}?
??
?
二、基于Socket的FTP服務器數據傳輸
? 其實上面的基于第三方包FtpClient的方法中,原理層也是基于Socket來進行通信的。所以,我們當然也可以使用Socket直接來寫這個FtpClient的代碼。下面給出基于Socket通信的結構構架圖。這里有一點需要大家注意一下,我們的FTP協議中有兩個端口(20和21)。通常情況下,我們的21號端口就是平時大家口口相傳的是FTP服務器的端口號,不過其實它只是FTP服務器中的命令端口號。它是負責傳送命令給FTP,一些操作如“登錄”、“改變目錄”、“刪除文件”,依靠這個連接發送命令就可完成。而對于20號端口號(也有可能是其它的一些端口號),對于有數據傳輸的操作,主要是顯示目錄列表,上傳、下載文件,我們需要依靠另一個Socket來完成。
? 所以在下面的結構圖中,我們可以看到我們有重新獲得端口號的過程,正是這個原因。
圖-2 基于Socket的FTP網絡文件傳輸圖
?
1.FTP連接
?
public void connectFtp() {try {mFtpClient = new Socket(Config.FTP.HOST_IP, Config.FTP.HOST_PORT);mReader = new BufferedReader(new InputStreamReader(mFtpClient.getInputStream()));mWriter = new BufferedWriter(new OutputStreamWriter(mFtpClient.getOutputStream()));sendCommand("USER " + Config.FTP.FTP_USERNAME);sendCommand("PASS " + Config.FTP.FTP_PASSWD);} catch (IOException e) {e.printStackTrace();}}?
2.向FTP服務器發送命令
?
?
private void sendCommand(String command) throws IOException {if (Tools.StringTools.isEmpty(command)) {return;}if (mFtpClient == null) {return;}mWriter.write(command + "\r\n");mWriter.flush();}?
3.向FTP服務器上傳文件
?
?
public void uploadFile(String localPath, String ftpPath) throws IOException {// 進入被動模式sendCommand("PASV");// 獲得ip和端口String response = readNewMessage();String[] ipPort = getIPPort(response);String ip = ipPort[0];int port = Integer.parseInt(ipPort[1]);// 建立數據端口的連接Socket dataSocket = new Socket(ip, port);sendCommand("STOR " + ftpPath);// 上傳文件前的準備File localFile = new File(localPath);OutputStream outputStream = dataSocket.getOutputStream();FileInputStream fileInputStream = new FileInputStream(localFile);// 上傳文件int offset;byte[] bytes = new byte[1024];while ((offset = fileInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, offset);}System.out.println("upload success!!");// 上傳文件后的善后工作outputStream.close();fileInputStream.close();dataSocket.close();}?
4.從FTP服務器下載文件
public void downloadFile(String localPath, String ftpPath) throws IOException {// 進入被動模式sendCommand("PASV");// 獲得ip和端口String response = readNewMessage();String[] ipPort = getIPPort(response);String ip = ipPort[0];int port = Integer.parseInt(ipPort[1]);// 建立數據端口的連接Socket dataSocket = new Socket(ip, port);sendCommand("RETR " + ftpPath);// 下載文件前的準備File localFile = new File(localPath);InputStream inputStream = dataSocket.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream(localFile);// 下載文件int offset;byte[] bytes = new byte[1024];while ((offset = inputStream.read(bytes)) != -1) {fileOutputStream.write(bytes, 0, offset);}System.out.println("download success!!");// 下載文件后的善后工作inputStream.close();fileOutputStream.close();dataSocket.close();}?
5.斷開FTP服務器連接
?
public void disconnectFtp() {if (mFtpClient == null) {return;}if (!mFtpClient.isConnected()) {return;}try {mFtpClient.close();} catch (IOException e) {e.printStackTrace();}}?
?
?
本文參考:
http://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/
?
源碼下載:
http://download.csdn.net/detail/u013761665/9264175
https://github.com/DemoForBlog/TransmissionOnFTP
總結
以上是生活随笔為你收集整理的Java连接FTP服务器并且实现对其文件的上传和下载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源项目托管GitHub的使用详述
- 下一篇: 数据挖掘:基于TF-IDF算法的数据集选