Java8實(shí)現(xiàn)FTP及SFTP文件上傳下載
有網(wǎng)上的代碼,也有自己的理解,代碼備份
一般連接windows服務(wù)器使用FTP,連接linux服務(wù)器使用SFTP。linux都是通過(guò)SFTP上傳文件,不需要額外安裝,非要使用FTP的話,還得安裝FTP服務(wù)(雖然剛開(kāi)始我就是這么干的)。
另外就是jdk1.8和jdk1.7之前的方法有些不同,網(wǎng)上有很多jdk1.7之前的介紹,本篇是jdk1.8的
添加依賴Jsch-0.1.54.jar
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch --> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
FTP上傳下載文件例子
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
/**
* Java自帶的API對(duì)FTP的操作
*/
public class Test {
private FtpClient ftpClient;
Test(){
/*
使用默認(rèn)的端口號(hào)、用戶名、密碼以及根目錄連接FTP服務(wù)器
*/
this.connectServer("192.168.56.130", 21, "jiashubing", "123456", "/home/jiashubing/ftp/anonymous/");
}
public void connectServer(String ip, int port, String user, String password, String path) {
try {
/* ******連接服務(wù)器的兩種方法*******/
ftpClient = FtpClient.create();
try {
SocketAddress addr = new InetSocketAddress(ip, port);
ftpClient.connect(addr);
ftpClient.login(user, password.toCharArray());
System.out.println("login success!");
if (path.length() != 0) {
//把遠(yuǎn)程系統(tǒng)上的目錄切換到參數(shù)path所指定的目錄
ftpClient.changeDirectory(path);
}
} catch (FtpProtocolException e) {
e.printStackTrace();
}
} catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
/**
* 關(guān)閉連接
*/
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 遠(yuǎn)程文件
*/
public void upload(String localFile, String remoteFile) {
File file_in = new File(localFile);
try(OutputStream os = ftpClient.putFileStream(remoteFile);
FileInputStream 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();
} catch (FtpProtocolException e) {
e.printStackTrace();
}
}
/**
* 下載文件。獲取遠(yuǎn)程機(jī)器上的文件filename,借助TelnetInputStream把該文件傳送到本地。
* @param remoteFile 遠(yuǎn)程文件路徑(服務(wù)器端)
* @param localFile 本地文件路徑(客戶端)
*/
public void download(String remoteFile, String localFile) {
File file_in = new File(localFile);
try(InputStream is = ftpClient.getFileStream(remoteFile);
FileOutputStream 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();
}catch (FtpProtocolException e) {
e.printStackTrace();
}
}
public static void main(String agrs[]) {
Test fu = new Test();
//下載測(cè)試
String filepath[] = {"aa.xlsx","bb.xlsx"};
String localfilepath[] = {"E:/lalala/aa.xlsx","E:/lalala/bb.xlsx"};
for (int i = 0; i < filepath.length; i++) {
fu.download(filepath[i], localfilepath[i]);
}
//上傳測(cè)試
String localfile = "E:/lalala/tt.xlsx";
String remotefile = "tt.xlsx"; //上傳
fu.upload(localfile, remotefile);
fu.closeConnect();
}
}
SFTP上傳下載文件例子
import com.jcraft.jsch.*;
import java.util.Properties;
/**
* 解釋一下SFTP的整個(gè)調(diào)用過(guò)程,這個(gè)過(guò)程就是通過(guò)Ip、Port、Username、Password獲取一個(gè)Session,
* 然后通過(guò)Session打開(kāi)SFTP通道(獲得SFTP Channel對(duì)象),再在建立通道(Channel)連接,最后我們就是
* 通過(guò)這個(gè)Channel對(duì)象來(lái)調(diào)用SFTP的各種操作方法.總是要記得,我們操作完SFTP需要手動(dòng)斷開(kāi)Channel連接與Session連接。
* @author jiashubing
* @since 2018/5/8
*/
public class SftpCustom {
private ChannelSftp channel;
private Session session;
private String sftpPath;
SftpCustom() {
/*
使用端口號(hào)、用戶名、密碼以連接SFTP服務(wù)器
*/
this.connectServer("192.168.56.130", 22, "jiashubing", "123456", "/home/ftp/");
}
SftpCustom(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String sftpPath) {
this.connectServer(ftpHost, ftpPort, ftpUserName, ftpPassword, sftpPath);
}
public void connectServer(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String sftpPath) {
try {
this.sftpPath = sftpPath;
// 創(chuàng)建JSch對(duì)象
JSch jsch = new JSch();
// 根據(jù)用戶名,主機(jī)ip,端口獲取一個(gè)Session對(duì)象
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
if (ftpPassword != null) {
// 設(shè)置密碼
session.setPassword(ftpPassword);
}
Properties configTemp = new Properties();
configTemp.put("StrictHostKeyChecking", "no");
// 為Session對(duì)象設(shè)置properties
session.setConfig(configTemp);
// 設(shè)置timeout時(shí)間
session.setTimeout(60000);
session.connect();
// 通過(guò)Session建立鏈接
// 打開(kāi)SFTP通道
channel = (ChannelSftp) session.openChannel("sftp");
// 建立SFTP通道的連接
channel.connect();
} catch (JSchException e) {
//throw new RuntimeException(e);
}
}
/**
* 斷開(kāi)SFTP Channel、Session連接
*/
public void closeChannel() {
try {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
} catch (Exception e) {
//
}
}
/**
* 上傳文件
*
* @param localFile 本地文件
* @param remoteFile 遠(yuǎn)程文件
*/
public void upload(String localFile, String remoteFile) {
try {
remoteFile = sftpPath + remoteFile;
channel.put(localFile, remoteFile, ChannelSftp.OVERWRITE);
channel.quit();
} catch (SftpException e) {
//e.printStackTrace();
}
}
/**
* 下載文件
*
* @param remoteFile 遠(yuǎn)程文件
* @param localFile 本地文件
*/
public void download(String remoteFile, String localFile) {
try {
remoteFile = sftpPath + remoteFile;
channel.get(remoteFile, localFile);
channel.quit();
} catch (SftpException e) {
//e.printStackTrace();
}
}
public static void main(String[] args) {
SftpCustom sftpCustom = new SftpCustom();
//上傳測(cè)試
String localfile = "E:/lalala/tt.xlsx";
String remotefile = "/home/ftp/tt2.xlsx";
sftpCustom.upload(localfile, remotefile);
//下載測(cè)試
sftpCustom.download(remotefile, "E:/lalala/tt3.xlsx");
sftpCustom.closeChannel();
}
}
Jsch-0.1.54.jar 學(xué)習(xí)了解
ChannelSftp類(lèi)是JSch實(shí)現(xiàn)SFTP核心類(lèi),它包含了所有SFTP的方法,如:
文件上傳put(),
文件下載get(),
進(jìn)入指定目錄cd().
得到指定目錄下的文件列表ls().
重命名指定文件或目錄rename().
刪除指定文件rm(),創(chuàng)建目錄mkdir(),刪除目錄rmdir().
大家引用方法時(shí)可以快速參考一下,具體傳參需參考源碼~
最后還要提一下的就是JSch支持的三種文件傳輸模式:
● APPEND 追加模式,如果目標(biāo)文件已存在,傳輸?shù)奈募⒃谀繕?biāo)文件后追加。
● RESUME 恢復(fù)模式,如果文件已經(jīng)傳輸一部分,這時(shí)由于網(wǎng)絡(luò)或其他任何原因?qū)е挛募鬏斨袛?,如果下一次傳輸相同的文件,則會(huì)從上一次中斷的地方續(xù)傳。
● OVERWRITE 完全覆蓋模式,這是JSch的默認(rèn)文件傳輸模式,即如果目標(biāo)文件已經(jīng)存在,傳輸?shù)奈募⑼耆采w目標(biāo)文件,產(chǎn)生新的文件。
FTP和SFTP區(qū)別
FTP是一種文件傳輸協(xié)議,一般是為了方便數(shù)據(jù)共享的。包括一個(gè)FTP服務(wù)器和多個(gè)FTP客戶端。FTP客戶端通過(guò)FTP協(xié)議在服務(wù)器上下載資源。而SFTP協(xié)議是在FTP的基礎(chǔ)上對(duì)數(shù)據(jù)進(jìn)行加密,使得傳輸?shù)臄?shù)據(jù)相對(duì)來(lái)說(shuō)更安全。但是這種安全是以犧牲效率為代價(jià)的,也就是說(shuō)SFTP的傳輸效率比FTP要低(不過(guò)現(xiàn)實(shí)使用當(dāng)中,沒(méi)有發(fā)現(xiàn)多大差別)。個(gè)人膚淺的認(rèn)為就是:一;FTP要安裝,SFTP不要安裝。二;SFTP更安全,但更安全帶來(lái)副作用就是的效率比FTP要低些。
建議使用sftp代替ftp。
主要因?yàn)椋?br />
1、可以不用額外安裝任何服務(wù)器端程序
2、會(huì)更省系統(tǒng)資源。
3、SFTP使用加密傳輸認(rèn)證信息和傳輸數(shù)據(jù),相對(duì)來(lái)說(shuō)會(huì)更安全。
4、也不需要單獨(dú)配置,對(duì)新手來(lái)說(shuō)比較簡(jiǎn)單(開(kāi)啟SSH默認(rèn)就開(kāi)啟了SFTP)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot使用SOFA-Lookout監(jiān)控的方法
本文介紹SpringBoot使用螞蟻金服SOFA-Lookout配合Prometheus進(jìn)行監(jiān)控,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔
這篇文章主要介紹了Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔,幫助大家更好的理解和使用Spring Boot框架,感興趣的朋友可以了解下2020-10-10
mybatis-plus如何修改日志只打印SQL語(yǔ)句不打印查詢結(jié)果
這篇文章主要介紹了mybatis-plus如何修改日志只打印SQL語(yǔ)句不打印查詢結(jié)果問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
Java中實(shí)現(xiàn)分布式定時(shí)任務(wù)的方法
這篇文章主要介紹了Java中實(shí)現(xiàn)分布式定時(shí)任務(wù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Java Calendar類(lèi)的使用總結(jié)實(shí)例
這篇文章主要介紹了Java Calendar類(lèi)的使用總結(jié)實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
SpringBoot中啟動(dòng)時(shí)如何忽略某項(xiàng)檢測(cè)
這篇文章主要介紹了SpringBoot中啟動(dòng)時(shí)如何忽略某項(xiàng)檢測(cè),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
深入學(xué)習(xí)Java單元測(cè)試(Junit+Mock+代碼覆蓋率)
在做單元測(cè)試時(shí),代碼覆蓋率常常被拿來(lái)作為衡量測(cè)試好壞的指標(biāo),甚至,用代碼覆蓋率來(lái)考核測(cè)試任務(wù)完成情況,比如,代碼覆蓋率必須達(dá)到80%或 90%。下面我們就來(lái)詳細(xì)學(xué)習(xí)下java單元測(cè)試吧2019-06-06

