java上传文件到sftp服务器
最近公司有個(gè)數(shù)據(jù)對(duì)接需求,合作方那邊是使用我們這邊的系統(tǒng)進(jìn)行出單的,數(shù)據(jù)首先也是在我們這邊。后面他們自己開發(fā)了業(yè)務(wù)系統(tǒng),需要我們這邊定時(shí)把每天的數(shù)據(jù)傳送到那邊去。他們那邊開發(fā)部門要求我們這邊,按一定的格式導(dǎo)出加簽加密的數(shù)據(jù)文件到他們的sftp服務(wù)器上面去。sftp代碼之前同事有寫過(guò)類似的代碼,就把他的給我啦,既然有了代碼,當(dāng)然要消化成自己的知識(shí)啦!這個(gè)過(guò)程中也遇到一些坑,就是我們上傳到sftp目錄的時(shí)候,文件一多我們就得隔開文件夾,一般都是按年月隔開的,但是sftp切換目錄后,如果目錄不存在,我們就新建目錄,這樣的邏輯是沒毛病,但是它沒辦法一次建多級(jí)目錄,比如/home 下面可以建/home/2022/ 沒辦法建/home/2022/03(會(huì)報(bào)異常),所以這個(gè)的話我們還得用循環(huán)來(lái)做。
一、代碼
先給大家看下代碼:
String userName = "";//賬號(hào)String password = ""; //密碼String host = ""; //ipint port=8889; //端口號(hào)String sftpUrl = "/application/data"; //上傳到sftp服務(wù)器 路徑String publicUrl = "E://"; //要上傳的文件String yyyy = DateUtils.formatDate(new Date(), "yyyy");String mm = DateUtils.formatDate(new Date(), "MM");String uploadUrl = sftpUrl + "/" + yyyy + "/" + mm;//存儲(chǔ)目錄地址List dirs = new ArrayList();dirs.add(0, jiangTaiFileUrl + "/" + yyyy + "/");dirs.add(1, jiangTaiFileUrl + "/" + yyyy + "/" + mm + "/");try {//1.獲取會(huì)話JSch jSch = new JSch();Session session = jSch.getSession(userName, host, port);session.setPassword(password);Properties properties = new Properties();properties.put("StrictHostKeyChecking", "no");session.setConfig(properties);session.connect();//2.獲取上傳的管道Channel channel = session.openChannel("sftp");channel.connect();sftp = (ChannelSftp) channel;if (!(uploadUrl == null || uploadUrl.trim().length() == 0)) {for (int index = 0; index < dirs.size(); index++) {//目錄不存在,新建目錄try {sftp.cd(uploadUrl);//進(jìn)入指定目錄break;} catch (SftpException e1) {try {sftp.cd(dirs.get(index).toString());} catch (SftpException e2) {try {sftp.mkdir(dirs.get(index).toString());sftp.cd(dirs.get(index).toString());} catch (SftpException e3) {logger.error("SFTP切換目錄出錯(cuò)!", e3);}}}}}//讀取源文件流(客戶端文件)InputStream client_fileInput = new FileInputStream(publicUrl );sftp.put(client_fileInput, “上傳后的文件名”);//傳送到服務(wù)端//5.關(guān)閉sftp.disconnect();client_fileInput.close();channel.disconnect();session.disconnect();logger.info("sftp傳輸成功");} catch (Exception e) {logger.info("sftp傳輸失敗: " + e.toString());e.printStackTrace();}一般上傳完文件后,需要?jiǎng)h除本地的文件以免占用空間
/*** 迭代刪除文件夾* @param dirPath 文件夾路徑*/public static void deleteDir(String dirPath) {File file = new File(dirPath);if(!file.exists()){return;}if(file.isFile()){file.delete();}else {File[] files = file.listFiles();if(files == null) {file.delete();}else {for (int i = 0; i < files.length; i++) {deleteDir(files[i].getAbsolutePath());}file.delete();}}}這里我遇到個(gè)坑,就是你們發(fā)現(xiàn)文件夾或者文件沒刪除或者沒刪除干凈,就要檢查一下流有沒有關(guān)閉,傳遞流的時(shí)候最好不要直接 xxx方法(new FileInputStream),用下面這種方式比較好,好排查問(wèn)題,哈哈。
FileInputStream file=new FileInputStream(""); xxx方法(file);file.close();
二、sftp連接過(guò)程
2.1、 JSch簡(jiǎn)介
JSch庫(kù)可以實(shí)現(xiàn)Java連接Linux服務(wù)器并操作命令、文件等,支持常用的各種授權(quán)模式。
3.1、JSch建立會(huì)話連接
從JSch對(duì)象中獲取Session,用于連接,并設(shè)置連接信息,賬號(hào)、密碼、服務(wù)器地址、端口號(hào)。
3.2 、 設(shè)置連接的參數(shù)配置
StrictHostKeyChecking=no 最不安全的級(jí)別,當(dāng)然也沒有那么多煩人的提示了,相對(duì)安全的內(nèi)網(wǎng)測(cè)試時(shí)建議使用。如果連接server的key在本地不存在,那么就自動(dòng)添加到文件中(默認(rèn)是known_hosts),并且給出一個(gè)警告。 StrictHostKeyChecking=ask 默認(rèn)的級(jí)別。如果連接和key不匹配,給出提示,并拒絕登錄。 StrictHostKeyChecking=yes 最安全的級(jí)別,如果連接與key不匹配,就拒絕連接,不會(huì)提示詳細(xì)信息。3.3、獲取文件上傳的通道
通過(guò)以上的步驟,我們與sftp服務(wù)器建立了連接后,我們需要獲取文件的傳輸通道Channel,并指定為sftp服務(wù),隨便進(jìn)行connect()連接。
3.3、常用命令
獲取了sftp通道,我們可以類似在linux下簡(jiǎn)單做一些shell指令操作:
mkdir()方法 創(chuàng)建目錄,只允許創(chuàng)建一級(jí)目錄
cd()方法 切換目錄
put()方法 上傳文件
rm()方法 刪除文件
還有很多,大家可以直接看對(duì)象的對(duì)應(yīng)方法就知道了,方法命名跟我們平時(shí)用的linux命令差不多。
3.4、用完一定要記得關(guān)閉各種連接跟流呀!!!!!!
總結(jié)
以上是生活随笔為你收集整理的java上传文件到sftp服务器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 华为手机怎样才算激活了_华为手机激活是怎
- 下一篇: 搜索关键词采集YouTube视频字幕