Java ftp 上傳檔案和下載檔案
阿新 • • 發佈:2018-12-16
今天同事問我一個ftp 上傳檔案和下載檔案功能應該怎麼做,當時有點懵逼,畢竟我也是第一次,然後裝了個逼,在網上找了一段程式碼發給同事,叫他除錯一下。結果悲劇了,執行不通過。(裝逼失敗)
我找的文章連結:http://blog.csdn.net/yucaifu1989/article/details/51483118
為了方便大家對比,我吧文章程式碼偷了過來:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import sun.net.TelnetInputStream; import sun.net.TelnetOutputStream; import sun.net.ftp.FtpClient; import sun.net.ftp.FtpProtocolException; /** * Java自帶的API對FTP的操作 * @Jdk:version 1.7 * @Title:Ftp.java * @author: boonya * @notice: 貌似此方法有個缺陷,不能操作大檔案 */ public class FtpJdk { /** * * 本地檔名 */ private String localfilename; /** * * 遠端檔名 */ private String remotefilename; /** * * FTP客戶端 */ private FtpClient ftpClient; /** * 伺服器連線 * * @param ip * 伺服器IP * @param port * 伺服器埠 * @param user * 使用者名稱 * @param password * 密碼 * @param path * 伺服器路徑 * @throws FtpProtocolException * */ public void connectServer(String ip, int port, String user, String password, String path) throws FtpProtocolException { try { /* ******連線伺服器的兩種方法****** */ // 第一種方法 /* * ftpClient =FtpClient.create(); * ftpClient.connect(new InetSocketAddress(ip, port)); */ // 第二種方法 ftpClient = FtpClient.create(ip); ftpClient.login(user, null, password); // 設定成2進位制傳輸 ftpClient.setBinaryType(); System.out.println("login success!"); if (path.length() != 0) { // 把遠端系統上的目錄切換到引數path所指定的目錄 ftpClient.changeDirectory(path); } ftpClient.setBinaryType(); } catch (IOException ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * 關閉連線 * */ public void closeConnect() { try { ftpClient.close(); System.out.println("disconnect success"); } catch (IOException ex) { System.out.println("not disconnect"); ex.printStackTrace(); throw new RuntimeException(ex); } } /** * * 上傳檔案 * * @param localFile * 本地檔案 * @param remoteFile * 遠端檔案 * @throws FtpProtocolException */ public void upload(String localFile, String remoteFile) throws FtpProtocolException { this.localfilename = localFile; this.remotefilename = remoteFile; TelnetOutputStream os = null; FileInputStream is = null; try { // 將遠端檔案加入輸出流中 os = (TelnetOutputStream) ftpClient.putFileStream(this.remotefilename, true); // 獲取本地檔案的輸入流 File file_in = new File(this.localfilename); is = new FileInputStream(file_in); // 建立一個緩衝區 byte[] bytes = new byte[1024]; int c; while ((c = is.read(bytes)) != -1) { os.write(bytes, 0, c); } System.out.println("upload success"); } catch (IOException ex) { System.out.println("not upload"); ex.printStackTrace(); throw new RuntimeException(ex); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } } } } /** * * 下載檔案 * * @param remoteFile * 遠端檔案路徑(伺服器端) * @param localFile * 本地檔案路徑(客戶端) * @throws FtpProtocolException * */ public void download(String remoteFile, String localFile) throws FtpProtocolException { TelnetInputStream is = null; FileOutputStream os = null; try { // 獲取遠端機器上的檔案filename,藉助TelnetInputStream把該檔案傳送到本地。 is = (TelnetInputStream) ftpClient.getFileStream(remoteFile); File file_in = new File(localFile); os = new FileOutputStream(file_in); byte[] bytes = new byte[1024]; int c; while ((c = is.read(bytes)) != -1) { os.write(bytes, 0, c); } System.out.println("download success"); } catch (IOException ex) { System.out.println("not download"); ex.printStackTrace(); throw new RuntimeException(ex); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } } } } /** * 函式入口 * * @param agrs */ public static void main(String agrs[]) { String filepath[] = { "/temp/aa.txt", "/temp/regist.log" }; String localfilepath[] = { "C:\\tmp\\1.txt", "C:\\tmp\\2.log" }; FtpJdk ftp = new FtpJdk(); /* * 使用預設的埠號、使用者名稱、密碼以及根目錄連線FTP伺服器 */ try { ftp.connectServer("127.0.0.1", 22, "boonya", "[email protected]", "/temp"); } catch (FtpProtocolException e) { e.printStackTrace(); } // 下載 for (int i = 0; i < filepath.length; i++) { try { ftp.download(filepath[i], localfilepath[i]); } catch (FtpProtocolException e) { e.printStackTrace(); } } String localfile = "E:\\contact.txt"; String remotefile = "/temp/records.txt"; // 上傳 try { ftp.upload(localfile, remotefile); } catch (FtpProtocolException e) { e.printStackTrace(); } ftp.closeConnect(); } }
順便把錯誤的log貼出來:
sun.net.ftp.FtpProtocolException: TYPE I:530 Please login with USER and PASS. at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:544) at sun.net.ftp.impl.FtpClient.setType(FtpClient.java:1668) at sun.net.ftp.FtpClient.setBinaryType(FtpClient.java:676) at ftp.FtpJdk.connectServer(FtpJdk.java:67) at ftp.FtpJdk.main(FtpJdk.java:248) not upload Disconnected from the target VM, address: '127.0.0.1:49353', transport: 'socket' java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read(BufferedInputStream.java:265) at sun.net.ftp.impl.FtpClient.readServerResponse(FtpClient.java:420) at sun.net.ftp.impl.FtpClient.readReply(FtpClient.java:497) at sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:532) at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:543) at sun.net.ftp.impl.FtpClient.openDataConnection(FtpClient.java:757) at sun.net.ftp.impl.FtpClient.putFileStream(FtpClient.java:1320) at ftp.FtpJdk.upload(FtpJdk.java:122) at ftp.FtpJdk.main(FtpJdk.java:269) Exception in thread "main" java.lang.RuntimeException: java.net.SocketTimeoutException: Read timed out at ftp.FtpJdk.upload(FtpJdk.java:140) at ftp.FtpJdk.main(FtpJdk.java:269) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read(BufferedInputStream.java:265) at sun.net.ftp.impl.FtpClient.readServerResponse(FtpClient.java:420) at sun.net.ftp.impl.FtpClient.readReply(FtpClient.java:497) at sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:532) at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:543) at sun.net.ftp.impl.FtpClient.openDataConnection(FtpClient.java:757) at sun.net.ftp.impl.FtpClient.putFileStream(FtpClient.java:1320) at ftp.FtpJdk.upload(FtpJdk.java:122) ... 1 more
有興趣的可以研究一下,希望找到原因的可以告訴一下博主,謝謝。
儘管博主裝逼失敗,但逼裝了,還是要繼續裝下去的,於是,找到了以下的辦法,博主親測成功,不成功可以聯絡博主。不多說直接貼程式碼:
用到的jar:
commons-net-1.4.1.jar
maven下載
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>1.4.1</version> </dependency>
ftp工具類:
package ftp.ftp2; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import sun.net.TelnetOutputStream; import sun.net.ftp.FtpProtocolException; import java.io.*; import java.net.SocketException; import java.util.Properties; public class FtpUtil { /** * 獲取FTPClient物件 * * @param ftpHost FTP主機伺服器 * @param ftpPassword FTP 登入密碼 * @param ftpUserName FTP登入使用者名稱 * @param ftpPort FTP埠 預設為21 * @return */ public static FTPClient getFTPClient(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) { FTPClient ftpClient = new FTPClient(); try { ftpClient = new FTPClient(); ftpClient.connect(ftpHost, ftpPort);// 連線FTP伺服器 ftpClient.login(ftpUserName, ftpPassword);// 登陸FTP伺服器 if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { System.out.println("未連線到FTP,使用者名稱或密碼錯誤。"); ftpClient.disconnect(); } else { System.out.println("FTP連線成功。"); } } catch (SocketException e) { e.printStackTrace(); System.out.println("FTP的IP地址可能錯誤,請正確配置。"); } catch (IOException e) { e.printStackTrace(); System.out.println("FTP的埠錯誤,請正確配置。"); } return ftpClient; } /* * 從FTP伺服器下載檔案 * * @param ftpHost FTP IP地址 * @param ftpUserName FTP 使用者名稱 * @param ftpPassword FTP使用者名稱密碼 * @param ftpPort FTP埠 * @param ftpPath FTP伺服器中檔案所在路徑 格式: ftptest/aa * @param localPath 下載到本地的位置 格式:H:/download * @param fileName 檔名稱 */ public static void downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String localPath, String fileName) { FTPClient ftpClient = null; try { ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); ftpClient.setControlEncoding("UTF-8"); // 中文支援 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); ftpClient.changeWorkingDirectory(ftpPath); File localFile = new File(localPath + File.separatorChar + fileName); OutputStream os = new FileOutputStream(localFile); ftpClient.retrieveFile(fileName, os); os.close(); ftpClient.logout(); } catch (FileNotFoundException e) { System.out.println("沒有找到" + ftpPath + "檔案"); e.printStackTrace(); } catch (SocketException e) { System.out.println("連線FTP失敗."); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); System.out.println("檔案讀取錯誤。"); e.printStackTrace(); } } /** * Description: 向FTP伺服器上傳檔案 * @param ftpHost FTP伺服器hostname * @param ftpUserName 賬號 * @param ftpPassword 密碼 * @param ftpPort 埠 * @param ftpPath FTP伺服器中檔案所在路徑 格式: ftptest/aa * @param fileName ftp檔名稱 * @param input 檔案流 * @return 成功返回true,否則返回false */ public static boolean uploadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String fileName,InputStream input) { boolean success = false; FTPClient ftpClient = null; try { int reply; ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return success; } ftpClient.setControlEncoding("UTF-8"); // 中文支援 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); ftpClient.changeWorkingDirectory(ftpPath); ftpClient.storeFile(fileName, input); input.close(); ftpClient.logout(); success = true; } catch (IOException e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException ioe) { } } } return success; } }
測試類:
package ftp.ftp2; import java.io.*; /** * Created by jyf on 2017/6/2. */ public class test { public static void main(String[] args) { String ftpHost = "172.16.114.10"; String ftpUserName = "user"; String ftpPassword = "a"; int ftpPort = 21; String ftpPath = "test2/"; String localPath = "F:\\11.txt"; String fileName = "11.txt"; //上傳一個檔案 try{ FileInputStream in=new FileInputStream(new File(localPath)); boolean test = FtpUtil.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName,in); System.out.println(test); } catch (FileNotFoundException e){ e.printStackTrace(); System.out.println(e); } //在FTP伺服器上生成一個檔案,並將一個字串寫入到該檔案中 try { InputStream input = new ByteArrayInputStream("test ftp jyf".getBytes("GBK")); boolean flag = FtpUtil.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName,input);; System.out.println(flag); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //下載一個檔案 FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName); } }