今天同事問我一個ftp 上傳文件和下載文件功能應該怎麼作,當時有點懵逼,畢竟我也是第一次,而後裝了個逼,在網上找了一段代碼發給同事,叫他調試一下。結果悲劇了,運行不經過。(裝逼失敗)java
爲了方便你們對比,我吧文章代碼偷了過來:apache
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", "user@", "/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
commons-net-1.4.1.jarsocket
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>1.4.1</version>
</dependency>maven
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); } }