兩種ftp使用java的實現方式 ,代碼都已測試
第一種:Serv-U FTP
先決條件:
1、Serv-U FTP服務器搭建成功。
2、jar包需要:版本不限制
<!--ftp上傳需要的jar-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>1.4.1</version>
</dependency>
實現代碼:
import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import javax.swing.*; import java.io.*; import java.net.SocketException; public class FtpUtil { private static FTPClient ftpClient = new FTPClient(); /** * 獲取FTPClient對象 * * @param ftpHost FTP主機服務器 * @param ftpPassword FTP 登錄密碼 * @param ftpUserName FTP登錄用戶名 * @param ftpPort FTP端口 默認為21 * @return */ public FTPClient getFTPClient(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) { try { 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 ftpPath FTP服務器中文件所在路徑 * @param localPath 下載到本地的位置 * @param fileName 文件名稱 */ public void downloadFtpFile( String ftpPath, String localPath, String fileName) { try { 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 ftpPath FTP服務器中文件所在路徑 格式: ftptest/aa * @param fileName ftp文件名稱 * @param input 文件流 * @return 成功返回true,否則返回false */ public boolean uploadFile( String ftpPath, String fileName,InputStream input) { boolean success = false; try { int reply; 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; } public static void main(String args[]){ String ftpHost = "127.0.0.1"; String ftpUserName = "servUFtp"; String ftpPassword = "14oioppii"; Integer port = 21; String ftpPath = "/"; String localPath = "F:\\"; String fileName = "text.jpg"; //上傳一個文件 try{ FileInputStream in=new FileInputStream(new File(localPath)); FtpUtil ftpUtil = new FtpUtil(); ftpUtil.getFTPClient(ftpHost, ftpUserName, ftpPassword, port); // 上傳文件 boolean flag = ftpUtil.uploadFile( ftpPath, fileName,in); // 下載文件 ftpUtil.downloadFtpFile( "/000.jpg", localPath, fileName); if(flag){ System.out.println("文件上傳ftp成功,請檢查ftp服務器。"); }else{ System.out.println("文件上傳ftp異常。請重試!"); } } catch (FileNotFoundException e){ e.printStackTrace(); System.out.println(e); } } }
第二種:SFTP
先決條件:
1、SFTP服務器搭建成功
2、jar需要:版本不限
<!--sftp上傳需要的jar-->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
實現代碼:
import com.jcraft.jsch.*; import java.io.*; import java.util.Properties; /** * @Author : guoyanan * @Title : Sftp工具類 * @Time : 2019/04/18 14:52 * @Document : 提供文件上傳功能 */ public class SFtpUtils { // 初始化單例對象 private static SFtpUtils sFtpUtils = new SFtpUtils(); private String host;//服務器連接ip private String username;//用戶名 private String password;//密碼 private int port = 22;//端口號 private ChannelSftp sftp = null; private Session sshSession = null; /** * 初始化sftp的單例對象 * @return */ public static SFtpUtils getInstance() { return sFtpUtils; } /** * 初始化sft鏈接信息,必須先做這個 * @param host 遠程主機ip * @param port 端口號 * @param username 賬號 * @param password 密碼 */ public void init(String host, int port, String username, String password) { this.host = host; this.username = username; this.password = password; this.port = port; } /** * 通過SFTP連接服務器 */ public void connect() { try { JSch jsch = new JSch(); jsch.getSession(username, host, port); sshSession = jsch.getSession(username, host, port); sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); Channel channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; } catch (Exception e) { e.printStackTrace(); } } /** * 關閉連接 */ public void disconnect() { if (this.sftp != null) { if (this.sftp.isConnected()) { this.sftp.disconnect(); } } if (this.sshSession != null) { if (this.sshSession.isConnected()) { this.sshSession.disconnect(); } } } /** * sftp下載文件 * @param remoteFielPath 遠程文件路徑 * @param localFilePath 本地下載路徑 * @return * @throws SftpException * @throws FileNotFoundException */ public boolean downLoadFile(String remoteFielPath,String localFilePath) throws SftpException, FileNotFoundException { // 檢查文件是否存在 SftpATTRS sftpATTRS = sftp.lstat(remoteFielPath); if(!sftpATTRS.isReg()){ // 不是一個文件,返回false return false; } // 下載文件到本地 sftp.get(remoteFielPath,localFilePath); return true; } /** * 下載文件放回文件數據 * @param remoteFielPath * @return * @throws SftpException * @throws IOException */ public boolean downLoadFileTwo(String remoteFielPath, String localFilePath) throws SftpException, IOException { // 檢查文件是否存在 SftpATTRS sftpATTRS = sftp.lstat(remoteFielPath); // 判斷是否是一個文件 if(sftpATTRS.isReg()){ // 下載文件到本地 InputStream inputStream = sftp.get(remoteFielPath); /**今天想寫下從sftp下載文件到本地,雖然sftp提供了get(String remotePath,String LocalPath)方法,將遠程文件寫入到本地。 * 但還是想屬性下從遠程獲取InputStream對象寫入到本地的方式。 * 遇到的問題:剛開始只想這實現,就是獲取byte對象寫入到本地文件,先用ByteArrayInputStream怎么轉都無法獲取到bytes對象 * 放入到FileOutputStream對象中。搞了老半天都沒有搞定,或許有ByteArrayInputStream對象下載的方式但沒有找到。 * 正解:如下*/ // 通過BufferedInputStream對象緩存輸入流對象獲取遠程的輸入流 BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); // 創建本地文件信息 File file = new File("F:\\456.jpg"); // 將本地文件放入到 本地文件輸出流 FileOutputStream fileOutputStream = new FileOutputStream(file); // 將本地文件輸出流 放入到 緩存輸出流對象 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); // 聲明每次獲取的byte長度 int len = 2048; // 初始化byte[] byte[] bytes = new byte[len]; /**通過BufferedInputStream對象獲取 遠程文件 InputStream的bytes字節信息,並循環添加到BufferedOutputStream緩存輸出流對象中, * 將遠程bytes數據寫入到本地文件中 * 遇到的問題:這里我一直糾結於為什么這樣寫會實現想要的效果,是如何寫入到本地的 * 其實這不是開發中遇到的問題的事情了,是自己困於自己設定的一個糾結情緒中了。也就是俗稱的牛角尖。 * 切記,一定不可以鑽牛角尖。因為開發都是有語言規則的。按照規則來就能實現效果,脫離規則即使神仙也無能為力。 * */ while ((len = bufferedInputStream.read(bytes)) != -1){ bufferedOutputStream.write(bytes,0,len); } bufferedOutputStream.flush(); bufferedInputStream.close(); bufferedOutputStream.close(); fileOutputStream.close(); inputStream.close(); return true; } return false; } /** * 上傳單個文件,通過文件路徑上傳 * @param remotePath:遠程保存目錄 * @param remoteFileName:保存文件名 * @param localPath:本地上傳目錄(以路徑符號結束) * @param localFileName:上傳的文件名 * @return */ public boolean uploadFile(String remotePath, String remoteFileName,String localPath, String localFileName) { FileInputStream in = null; try { // 創建目錄 createDir(remotePath); File file = new File(localPath + localFileName); in = new FileInputStream(file); sftp.put(in, remoteFileName); return true; }catch (FileNotFoundException e) { e.printStackTrace(); }catch (SftpException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 上傳文件到sftp,通過輸入流上傳 * @param remotePath * @param remoteFileName * @param inputStream * @return */ public boolean uploadFile(String remotePath, String remoteFileName,InputStream inputStream) { FileInputStream in = null; try { // 創建目錄 createDir(remotePath); sftp.put(inputStream, remoteFileName); return true; }catch (SftpException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 創建目錄 * @param createpath * @return */ public boolean createDir(String createpath) { try { if (isDirExist(createpath)) { // 有時候,開發在填寫路徑的時候第一個位置會忘記加"/"的根路徑 // 這回引發cd操作是發生:NO Such File 異常,所以這里處理下 if(!(createpath.substring(0,1)=="/")){ createpath="/"+createpath; } this.sftp.cd(createpath); return true; } String pathArry[] = createpath.split("/"); StringBuffer filePath = new StringBuffer("/"); for (String path : pathArry) { if (path.equals("")) { continue; } filePath.append(path + "/"); if (isDirExist(filePath.toString())) { sftp.cd(filePath.toString()); } else { // 建立目錄 sftp.mkdir(filePath.toString()); // 進入並設置為當前目錄 sftp.cd(filePath.toString()); } } this.sftp.cd(createpath); return true; } catch (SftpException e) { e.printStackTrace(); } return false; } /** * 判斷目錄是否存在,linux目錄必須最前方帶有"/" * @param directory * @return */ public boolean isDirExist(String directory) { boolean isDirExistFlag = false; try { // 有時候,開發在填寫路徑的時候第一個位置會忘記加"/"的根路徑 // 這回引發cd操作是發生:NO Such File 異常,所以這里處理下 if(!(directory.substring(0,1)=="/")){ directory="/"+directory; } SftpATTRS sftpATTRS = sftp.lstat(directory); isDirExistFlag = true; return sftpATTRS.isDir(); } catch (Exception e) { if (e.getMessage().toLowerCase().equals("no such file")) { isDirExistFlag = false; } } return isDirExistFlag; } public static void main(String arg[]) throws IOException, SftpException { // 獲取圖片的InputStream對象,並將圖片生成到sftp上 SFtpUtils sFtpUtils= SFtpUtils.getInstance(); sFtpUtils.init("127.0.0.1",22, "sftpuser", "UIOPOopi"); sFtpUtils.connect(); // 上傳文件 /*File file = new File("F:\\OK.jpg"); InputStream in = new FileInputStream(file); boolean flag = sFtpUtils.uploadFile("/app/xwapp/Test","1111.jpg",in);*/ // 下載文件到本地方法1 // boolean flag = sFtpUtils.downLoadFile("/app/xwapp/Test/1111.jpg","F:\\OKbak.jpg"); // 下載文件到本地方法2 boolean flag = sFtpUtils.downLoadFileTwo("/app/xwapp/Test/1111.jpg","F:\\OKbak.jpg"); if(flag){ System.out.println("處理成功"); }else { System.out.println("處理失敗"); } sFtpUtils.disconnect(); } }