Java讀取傳輸FTP文件實(shí)現(xiàn)示例
一.需求
FTP作為文件服務(wù)器,由提供服務(wù)方提供遠(yuǎn)程連接地址,連接端口,賬號(hào),密碼等信息。
根據(jù)以上信息可以建立客戶端連接,隨后對(duì)于建立好的連接可進(jìn)行文件讀取,文件上傳等操作
二.依賴
<!-- FTP相關(guān)操作的依賴 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
</dependency>
<!-- IO工具類的依賴 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<!-- lombok依賴 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>三.關(guān)鍵源碼
3.0 配置信息
ftp:
config:
host: ${env.ftp.config.host:10.1.1.1}
port: ${env.ftp.config.port:12345}
username: ${env.ftp.config.username:ftpUsername}
password: ${env.ftp.config.password:ftpPwd}
remote-dir-path: ${env.ftp.config.remote-dir-path:/}/**
* @author: Vainycos
* @description ftp配置信息
* @date: 2023/4/17 15:16
*/
@Data
@Component
@ConfigurationProperties("ftp.config")
public class FtpConfig {
private String host;
private int port;
private String username;
private String password;
/** 初始讀取根目錄,當(dāng)前默認(rèn)/ */
private String remoteDirPath;
}3.1 獲取客戶端
/**
* 獲取ftp客戶端
* @return
*/
public FTPClient getFtpClient(){
try {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(ftpConfig.getHost() ,ftpConfig.getPort());
// 10分鐘連接時(shí)間
ftpClient.setConnectTimeout(600000);
ftpClient.setDefaultTimeout(600000);
ftpClient.login(ftpConfig.getUsername() ,ftpConfig.getPassword());
// login后設(shè)置傳輸?shù)哪J?
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// login后設(shè)置被動(dòng)模式
ftpClient.enterLocalPassiveMode();
// login后設(shè)置編碼
String LOCAL_CHARSET = "GBK";
// 開啟服務(wù)器對(duì)UTF-8的支持,如果服務(wù)器支持就用UTF-8編碼,否則就使用本地編碼(GBK).
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.error("未連接到FTP,用戶名或密碼錯(cuò)誤!");
ftpClient.disconnect();
} else {
log.info("FTP連接成功!");
}
// 切換從某個(gè)根目錄下開始掃描
ftpClient.changeWorkingDirectory(ftpConfig.getRemoteDirPath());
return ftpClient;
}catch (IOException e) {
log.error("ftp建立連接異常->{}", e);
}
return null;
}3.2 獲取ftp文件
/**
* 獲取對(duì)應(yīng)目錄下的第一級(jí)目錄文件
* @param ftpClient client
* @throws IOException
*/
public void getFtpFirstDirectoryFiles(FTPClient ftpClient) throws IOException {
? ? log.info("ftpclient當(dāng)前工作目錄->{}", ftpClient.printWorkingDirectory());
? ? if (ftpClient != null) {
? ? ? ? FTPFile[] files = ftpClient.listFiles();
? ? ? ? for (FTPFile file : files) {
? ? ? ? ? ? String fileName = file.getName();
? ? ? ? ? ? if (file.isDirectory()){
? ? ? ? ? ? ? ? // 每次從根目錄下查找第一級(jí)目錄
? ? ? ? ? ? ? ? String firstDirectory = ftpConfig.getRemoteDirPath() + "/" + fileName;
? ? ? ? ? ? ? ? ftpClient.changeWorkingDirectory(firstDirectory);
? ? ? ? ? ? ? ? log.info("當(dāng)前目錄->{}, 開始掃描錄音文件", firstDirectory);
? ? ? ? ? ? ? ? // 切換目錄后直接遍歷第一級(jí)的文件,不遞歸第二級(jí)目錄
? ? ? ? ? ? ? ? dealFile(ftpClient);
? ? ? ? ? ? ? ? log.info("{}->目錄掃描結(jié)束", firstDirectory);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
/**
?* 處理目錄下的文件
?* @param ftpClient
?* @throws IOException
?*/
public void dealFile(FTPClient ftpClient) throws IOException {
?? ?FTPFile[] files = ftpClient.listFiles();
? ? ? ? for (FTPFile file : files) {
?? ? ? ? ? ?String fileName = file.getName();
? ? ? ? ? ? if (file.isDirectory()) {
? ? ? ? ? ? ? ? log.info("{}->為目錄,跳過", fileName);
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? String rootWorkingDirectory = ftpClient.printWorkingDirectory();
? ? ? ? ? ? log.info("獲取到文件->{}, 開始獲取ftp文件流, ftpclient工作目錄->{}", fileName, ftpClient.printWorkingDirectory());
? ? ? ? ? ? // 開始獲取ftp文件流
? ? ? ? ? ? InputStream inputStream = ftpClient.retrieveFileStream(new String(fileName.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING));
? ? ? ? ? ? if (inputStream == null){
? ? ? ? ? ? ? ? log.error("文件不存在->{}", fileName);
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? byte[] data = IOUtils.toByteArray(inputStream);
? ? ? ? ? ? inputStream.close();
? ? ? ? ? ? // 關(guān)鍵代碼,如果不執(zhí)行該代碼,后續(xù)的ftpClient操作將會(huì)不生效
? ? ? ? ? ? ftpClient.completePendingCommand();
? ? ? ? ? ? // 省略...獲取到了inputStream 文件流進(jìn)行后續(xù)處理
? ? ? ??? ?}
}3.3 關(guān)閉ftp服務(wù)連接
/**
* 關(guān)閉FTP服務(wù)連接
* @param ftpClient
*/
public void disConnection(FTPClient ftpClient) {
try{
if(ftpClient.isConnected()){
ftpClient.disconnect();
}
}catch(IOException e) {
log.error("ftpClient.disconnect失敗->{}", e);
}
}四.總結(jié)
上述源碼僅供參考,具體需根據(jù)實(shí)際業(yè)務(wù)需求進(jìn)行調(diào)整。主要注意點(diǎn)為讀取中文文件名的文件以及獲取ftpClient文件流之后的處理,已標(biāo)注在注釋中,希望能夠幫助讀者少踩坑。
參考資料
基于ftp協(xié)議的文件變化主動(dòng)監(jiān)聽
FTPSClient解決無(wú)法獲取文件問題(listFiles為空)
ftpClient.retrieveFileStream導(dǎo)致FTPClient的后面操作失敗
到此這篇關(guān)于Java讀取傳輸FTP文件實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Java讀取傳輸FTP文件 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java設(shè)計(jì)模式之創(chuàng)建者模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之創(chuàng)建者模式詳解,創(chuàng)建者模式,顧名思義,就是提供友好的創(chuàng)建對(duì)象的方式?,對(duì)象都是?new?出來(lái)的,但是在一些情況下,這種方式不是很友好,首先,它不夠直觀,需要的朋友可以參考下2023-08-08
springboot使用Mybatis-plus分頁(yè)插件的案例詳解
這篇文章主要介紹了springboot使用Mybatis-plus分頁(yè)插件的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
Java Collections.shuffle()方法案例詳解
這篇文章主要介紹了Java Collections.shuffle()方法案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
關(guān)于SpringBoot配置文件application.properties的路徑問題
這篇文章主要介紹了關(guān)于SpringBoot配置文件application.properties的路徑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
java省市級(jí)聯(lián)下拉菜單實(shí)例代碼
這篇文章主要為大家詳細(xì)介紹了java省市級(jí)聯(lián)實(shí)例代碼,具有一定的參考價(jià)值,感興趣的朋友可以參考一下2016-05-05
Java 自定義Spring框架與Spring IoC相關(guān)接口分析
Spring框架是由于軟件開發(fā)的復(fù)雜性而創(chuàng)建的。Spring使用的是基本的JavaBean來(lái)完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限于服務(wù)器端的開發(fā)2021-10-10
SpringBoot全局異常處理與定制404頁(yè)面的方法
這篇文章主要介紹了SpringBoot全局異常處理與定制404頁(yè)面的相關(guān)資料,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2007-09-09

