Java實(shí)現(xiàn)讀取SFTP服務(wù)器指定目錄文件的方法
SFTP服務(wù)器的簡(jiǎn)介
SFTP(SSH File Transfer Protocol)是一種在安全通道上傳輸文件的協(xié)議,它是基于SSH(Secure Shell)協(xié)議的擴(kuò)展,用于在客戶端和服務(wù)器之間進(jìn)行加密的文件傳輸。
SFTP 服務(wù)器的主要作用是提供一個(gè)安全的方式來(lái)上傳、下載和管理文件。以下是一些 SFTP 服務(wù)器的主要作用:
- 安全的文件傳輸: SFTP 使用加密通道傳輸數(shù)據(jù),確保數(shù)據(jù)在傳輸過(guò)程中不會(huì)被竊聽(tīng)或篡改。這使得 SFTP成為一種安全的文件傳輸方式,適用于敏感數(shù)據(jù)或機(jī)密文件的傳輸。
- 遠(yuǎn)程文件管理: SFTP服務(wù)器允許用戶通過(guò)遠(yuǎn)程連接訪問(wèn)和管理服務(wù)器上的文件和目錄。用戶可以上傳、下載、重命名、刪除等操作,就像在本地操作文件一樣。
- 備份和歸檔: 組織可以使用 SFTP 服務(wù)器來(lái)進(jìn)行文件的備份和歸檔。通過(guò)定期將文件上傳到 SFTP服務(wù)器上,可以確保文件的安全存儲(chǔ)和恢復(fù)。
- 遠(yuǎn)程工作: SFTP 服務(wù)器使得遠(yuǎn)程工作變得更加方便。用戶可以在任何地方通過(guò) SFTP客戶端訪問(wèn)和處理服務(wù)器上的文件,無(wú)需物理接觸服務(wù)器。
- 數(shù)據(jù)共享: SFTP 服務(wù)器可以用于在團(tuán)隊(duì)成員之間共享文件。成員可以通過(guò) SFTP 進(jìn)行文件的共享和協(xié)作,而無(wú)需將文件發(fā)送給其他人。
- 自動(dòng)化流程: SFTP 服務(wù)器可以與自動(dòng)化腳本或工作流程集成,實(shí)現(xiàn)自動(dòng)上傳、下載和處理文件,從而提高工作效率。
- 批量處理: SFTP 服務(wù)器支持批量上傳和下載文件,適用于需要同時(shí)處理多個(gè)文件的場(chǎng)景,如數(shù)據(jù)導(dǎo)入、導(dǎo)出等。
總之,SFTP 服務(wù)器提供了一個(gè)安全、高效的方式來(lái)進(jìn)行文件傳輸和管理,適用于許多不同的應(yīng)用場(chǎng)景,特別是在需要保護(hù)數(shù)據(jù)安全性的情況下。
pom依賴
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>${jsch.version}</version> </dependency> <jsch.version>0.1.55</jsch.version>
實(shí)現(xiàn)代碼
import cn.hutool.core.text.CharSequenceUtil; import com.jcraft.jsch.*; import com.woodare.cdw.core.Cons; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.FileCopyUtils; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Properties; /** * @author Jalen */ public class SftpHelper { private static final Logger log = LoggerFactory.getLogger(SftpHelper.class); private ChannelSftp sftp; private Session session; /** * SFTP login name */ private String username; /** * SFTP login password */ private String password; /** * Private key */ private String privateKey; /** * SFTP server ip address */ private String host; /** * SFTP server port */ private Integer port; private String directory; private List<String> listedFiles; private List<String> fileNames; /** * Construct sftp object based on password authentication */ public SftpHelper(String username, String password, String host, Integer port) { this.username = username; this.password = password; this.host = host; this.port = port; } /** * Construct sftp object based on key authentication */ public SftpHelper(String username, String host, Integer port, String privateKey) { this.username = username; this.host = host; this.port = port; this.privateKey = privateKey; } public SftpHelper() { } public List<String> getFileNames() { return this.fileNames; } public SftpHelper connectSftp(String filePath, String fileName) { SftpHelper sftp = new SftpHelper(username, password, host, port); sftp.login().find(filePath, fileName); if (!sftp.isExistsFile()) { log.info(" importDealerData, file no found "); return null; } return sftp; } /** * login sftp server */ public SftpHelper login() { try { JSch jsch = new JSch(); if (privateKey != null) { // Set private key jsch.addIdentity(privateKey); } session = jsch.getSession(username, host, Optional.ofNullable(port).orElse(0)); if (password != null) { session.setPassword(password); } Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); Channel channel = session.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; } catch (JSchException e) { log.warn("sftp login failed, reason:{}", e.getMessage()); } return this; } /** * log out */ public void logout() { if (sftp != null) { if (sftp.isConnected()) { sftp.disconnect(); } } if (session != null) { if (session.isConnected()) { session.disconnect(); } } } /** * Upload the input stream data to sftp as a file. File full path = basePath + directory * * @author Jalen * @date 2022/8/29 15:46 * @param basePath * basePath * @param directory * directory * @param sftpFileName * sftpFileName * @param file * file */ public void upload(String basePath, String directory, String sftpFileName, File file) { if (file == null || CharSequenceUtil.isEmpty(sftpFileName) || (CharSequenceUtil.isEmpty(basePath) && CharSequenceUtil.isEmpty(directory))) { log.error("upload basePath:{} directory:{} sftpFileName:{} failed, reason:{}", basePath, directory, sftpFileName, "Parameters are empty"); return; } try { if (CharSequenceUtil.isNotEmpty(basePath)) { sftp.cd(basePath); } if (CharSequenceUtil.isNotEmpty(directory)) { sftp.cd(directory); } } catch (SftpException e) { // If the directory does not exist, create a folder String[] dirs = directory.split("/"); String tempPath = basePath; for (String dir : dirs) { if (null == dir || "".equals(dir)) { continue; } tempPath += "/" + dir; try { sftp.cd(tempPath); } catch (SftpException ex) { try { sftp.mkdir(tempPath); sftp.cd(tempPath); } catch (SftpException sftpException) { log.error("upload basePath:{} directory:{} sftpFileName:{} failed, reason:{}", basePath, directory, sftpFileName, e.getMessage()); } } } } InputStream input = null; try { input = new FileInputStream(file); sftp.put(input, sftpFileName); } catch (FileNotFoundException | SftpException e) { log.error("upload basePath:{} directory:{} sftpFileName:{} failed, reason:{}", basePath, directory, sftpFileName, e.getMessage()); } finally { if (input != null) { try { input.close(); } catch (IOException e) { log.error("upload basePath:{} directory:{} sftpFileName:{} failed, Reason:{}", basePath, directory, sftpFileName, e.getMessage()); } } } } /** * download file. * * @author Jalen * @date 2022/8/29 15:46 * @param directory * directory * @param downloadFile * downloadFile * @param saveFile * saveFile * @return boolean */ public boolean download(String directory, String downloadFile, String saveFile) throws SftpException, IOException { FileOutputStream outPutFile = null; try { if (CharSequenceUtil.isNotEmpty(directory)) { sftp.cd(directory); } // The folder cannot be operated, otherwise an error will be // reported. String filepath = saveFile + downloadFile; File file = new File(filepath); outPutFile = new FileOutputStream(file.getPath()); sftp.get(downloadFile, outPutFile); } catch (Exception e) { log.warn("download directory:{} downloadFile:{} failed, reason:{}", directory, downloadFile, e.getMessage()); return false; } finally { if (outPutFile != null) { outPutFile.close(); } } return true; } /** * download file * * @author Jalen * @date 2022/8/29 15:47 * @param directory * directory * @param downloadFile * downloadFile * @return byte[] */ public byte[] download(String directory, String downloadFile) throws SftpException, IOException { if (CharSequenceUtil.isNotEmpty(directory)) { sftp.cd(directory); } InputStream is = sftp.get(downloadFile); return FileCopyUtils.copyToByteArray(is); } public InputStream downloadInputStream(String directory, String downloadFile) throws SftpException { if (CharSequenceUtil.isNotEmpty(directory)) { sftp.cd(directory); } return sftp.get(downloadFile); } /** * Delete sftp file * * @author Jalen * @date 2022/8/29 15:47 * @param directory * directory * @param deleteFile * deleteFile * @return boolean */ public boolean delete(String directory, String deleteFile) { boolean flag; try { // The full path can be the directory contained in the current // directory sftp.cd(directory); // Delete the full suffixed file name of the file sftp.rm(deleteFile); flag = true; } catch (Exception e) { log.info("delete directory:{} deleteFile:{} failed, reason:{}", directory, deleteFile, e.getMessage()); flag = false; } return flag; } public Boolean isValidFile(String fileName) { boolean isValid = false; if (CharSequenceUtil.isNotEmpty(fileName)) { String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); boolean exist = CharSequenceUtil.isNotEmpty(fileType) && (fileType.equalsIgnoreCase(Cons.File.CSV) || fileType.equalsIgnoreCase(Cons.File.XLS) || fileType.equalsIgnoreCase(Cons.File.TXT) || fileType.equalsIgnoreCase(Cons.File.XLSX)); if (exist) { isValid = true; } } return isValid; } public SftpHelper find(String directory, String fileName) { this.directory = directory; this.listedFiles = listFiles(directory, fileName); return this; } public boolean isExistsFile() { return this.listedFiles != null && this.listedFiles.size() > 0; } private boolean matchFile(String target, String pattern) { return target.equals(pattern) || target.matches(pattern); } public List<String> listFiles(String directory, String fileName) { List<String> findFileList = new ArrayList<>(); ChannelSftp.LsEntrySelector selector = lsEntry -> { String lsFileName = lsEntry.getFilename(); if (CharSequenceUtil.isNotEmpty(fileName)) { if (matchFile(lsFileName, fileName)) { findFileList.add(lsFileName); } } else { Boolean isValid = isValidFile(lsFileName); if (isValid) { findFileList.add(lsFileName); } } return 0; }; try { if (CharSequenceUtil.isNotEmpty(directory)) { sftp.ls(directory, selector); } } catch (SftpException e) { log.info("listFiles failed, reason:{}", e.getMessage()); } return findFileList; } public String getDirectory() { return directory; } public void setDirectory(String directory) { this.directory = directory; } public List<String> getListedFiles() { return listedFiles; } public void setListedFiles(List<String> listedFiles) { this.listedFiles = listedFiles; }
使用案例
public void synData() throws Exception { // Only us will synchronize data with siebel SftpHelper sftp = this.connectSftp(siebelSynFilePath, null); if (ObjectUtil.isNull(sftp)) { log.warn(" Files is empty. "); return; } List<String> listedFiles = sftp.getListedFiles(); // CN 真實(shí)場(chǎng)景, 讀取ftp目錄 List<BoatSynData> boatEntityList = new ArrayList<>(); List<EngineSynData> engineEntityList = new ArrayList<>(); List<AccountEntity> accountEntityList = new ArrayList<>(); List<AccountSettingsEntity> accountSettingsEntityList = new ArrayList<>(); List<AccountAreaInterestsEntity> accountAreaInterestsEntityList = new ArrayList<>(); List<ServiceReminderEntity> serviceReminderEntityList = new ArrayList<>(); List<ClaimEntity> claimEntityList = new ArrayList<>(); List<CampaignEntity> campaignEntityList = new ArrayList<>(); // CN 只讀取當(dāng)天文件 for (String listedFile : listedFiles) { String name = listedFile; InputStream fileInputStream = sftp.downloadInputStream(siebelSynFilePath, listedFile); if (CharSequenceUtil.isBlank(name)) { throw new IllegalArgumentException(" Filename is not empty."); } name = name.substring(0, name.indexOf(Cons.Delimiter.UNDERSCORE)); switch (name) { case SiebelCons.BOAT -> boatEntityList = SynFileProxy.parseFile(name, fileInputStream, BoatSynData.class); case SiebelCons.ENGINE -> engineEntityList = SynFileProxy.parseFile(name, fileInputStream, EngineSynData.class); case SiebelCons.ACCOUNT -> accountEntityList = SynFileProxy.parseFile(name, fileInputStream, AccountEntity.class); case SiebelCons.ACCOUNT_SETTINGS -> accountSettingsEntityList = SynFileProxy.parseFile(name, fileInputStream, AccountSettingsEntity.class); case SiebelCons.SERVICE_REMINDER -> serviceReminderEntityList = SynFileProxy.parseFile(name, fileInputStream, ServiceReminderEntity.class); case SiebelCons.CLAIM -> claimEntityList = SynFileProxy.parseFile(name, fileInputStream, ClaimEntity.class); case SiebelCons.AREA_INT -> accountAreaInterestsEntityList = SynFileProxy.parseFile(name, fileInputStream, AccountAreaInterestsEntity.class); case SiebelCons.CAMPAIGN -> campaignEntityList = SynFileProxy.parseFile(name, fileInputStream, CampaignEntity.class); default -> { } } } // CN 合并數(shù)據(jù)入庫(kù) this.handleAccount(accountEntityList); this.handleAccountSettings(accountSettingsEntityList); this.handleReminder(serviceReminderEntityList); this.handleClaim(claimEntityList); this.handleBoat(boatEntityList); this.handleEngine(engineEntityList); this.handleAccountAreaInterests(accountAreaInterestsEntityList); this.handleCampaign(campaignEntityList); // CN 操作完成刪除文件 for (String listedFile : listedFiles) { sftp.delete(siebelSynFilePath, listedFile); } }
到此這篇關(guān)于Java實(shí)現(xiàn)讀取SFTP服務(wù)器指定目錄文件的文章就介紹到這了,更多相關(guān)java讀取SFTP服務(wù)器指定目錄文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)24點(diǎn)紙牌游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)24點(diǎn)紙牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03SpringBoot實(shí)現(xiàn)接口防刷的兩種方法
接口被刷指的是同一接口被頻繁調(diào)用,可能是由于以下原因?qū)е拢簮阂夤艉驼`操作或程序錯(cuò)誤,本文給大家介紹了SpringBoot實(shí)現(xiàn)接口防刷的兩種方法,并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-06-06Spring框架配置java web實(shí)現(xiàn)實(shí)例化
這篇文章主要介紹了Spring框架配置java web實(shí)現(xiàn)實(shí)例化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Maven編譯錯(cuò)誤:程序包c(diǎn)om.sun.*包不存在的三種解決方案
J2SE中的類大致可以劃分為以下的各個(gè)包:java.*,javax.*,org.*,sun.*,本文文章主要介紹了maven編譯錯(cuò)誤:程序包c(diǎn)om.sun.xml.internal.ws.spi不存在的解決方案,感興趣的可以了解一下2024-02-02spring+springmvc+mybatis 開(kāi)發(fā)JAVA單體應(yīng)用
這篇文章主要介紹了spring+springmvc+mybatis 開(kāi)發(fā)JAVA單體應(yīng)用的相關(guān)知識(shí),本文通過(guò)圖文實(shí)例代碼的形式給大家介紹的非常詳細(xì) ,需要的朋友可以參考下2018-11-11Spring-全面詳解(學(xué)習(xí)總結(jié))
這篇文章主要介紹了詳解Spring框架入門(mén),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望能給你帶來(lái)幫助2021-07-07eclipse創(chuàng)建多層包(多級(jí)包)全過(guò)程
這篇文章主要介紹了eclipse創(chuàng)建多層包(多級(jí)包)全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11MyBatis-plus使用lambda條件構(gòu)造器報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了MyBatis-plus使用lambda條件構(gòu)造器報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01spring security實(shí)現(xiàn)下次自動(dòng)登錄功能過(guò)程解析
這篇文章主要介紹了spring security實(shí)現(xiàn)記住我下次自動(dòng)登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11