springboot如何讀取sftp的文件
springboot讀取sftp的文件
1.添加pom依賴(基於springboot項目)
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
2.application.yaml配置文件
sftp: ip: 192.168.1.102 port: 22 username: admin password: admin root: /img #文件根目錄
3.工具類
import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; import lombok.extern.slf4j.Slf4j; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; import java.util.concurrent.TimeUnit; /** * */ @Slf4j public class SFTPUtil { /** * 下載重試次數 */ private static final int DOWNLOAD_RETRY = 3; /** * 下載重試間隔時間 單位毫秒 */ private static final long DOWNLOAD_SLEEP = 3 * 1000; private static final SFTPUtil SFTP = new SFTPUtil(); private static ChannelSftp client; private static Session session; /** * @return */ public static SFTPUtil getInstance() { return SFTP; } /** * 獲取SFTP連接 * * @param username * @param password * @param ip * @param port * @return */ synchronized public ChannelSftp makeConnection(String username, String password, String ip, int port) { if (client == null || session == null || !client.isConnected() || !session.isConnected()) { try { JSch jsch = new JSch(); session = jsch.getSession(username, ip, port); if (password != null) { session.setPassword(password); } Properties config = new Properties(); // 設置第一次登陸的時候主機公鑰確認提示,可選值:(ask | yes | no) config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); //sftp協議 Channel channel = session.openChannel("sftp"); channel.connect(); client = (ChannelSftp) channel; log.info("sftp connected success,connect to [{}:{}], username [{}]", ip, port, username); } catch (JSchException e) { log.error("sftp connected fail,connect to [{}:{}], username [{}], password [{}], error message : [{}]", ip, port, username, password, e.getMessage()); } } return client; } /** * * 關閉連接 server */ public static void close() { if (client != null && client.isConnected()) { client.disconnect(); } if (session != null && session.isConnected()) { session.disconnect(); } } /** * 單次下載文件 * * @param downloadFile 下載文件地址 * @param saveFile 保存文件地址 * @param ip 主機地址 * @param port 主機端口 * @param username 用戶名 * @param password 密碼 * @param rootPath 根目錄 * @return */ public synchronized static File download(String downloadFile, String saveFile, String ip, Integer port, String username, String password, String rootPath) { boolean result = false; File file = null; Integer i = 0; while (!result) { //獲取連接 ChannelSftp sftp = getInstance().makeConnection(username, password, ip, port); FileOutputStream fileOutputStream = null; log.info("sftp file download start, target filepath is {}, save filepath is {}", downloadFile, saveFile); try { sftp.cd(rootPath); file = new File(saveFile); if (file.exists()) { file.delete(); } else { file.createNewFile(); } fileOutputStream = new FileOutputStream(file); sftp.get(downloadFile, fileOutputStream); result = true; } catch (FileNotFoundException e) { log.error("sftp file download fail, FileNotFound: [{}]", e.getMessage()); } catch (IOException e) { log.error("sftp file download fail, IOException: [{}]", e.getMessage()); } catch (SftpException e) { i++; log.error("sftp file download fail, sftpException: [{}]", e.getMessage()); if (i > DOWNLOAD_RETRY) { log.error("sftp file download fail, retry three times, SftpException: [{}]", e.getMessage()); return file; } try { TimeUnit.MILLISECONDS.sleep(DOWNLOAD_SLEEP); } catch (InterruptedException ex) { ex.printStackTrace(); } } finally { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } SFTPUtil.close(); } return file; } /** * 下載文件 * * @param downloadFile 下載文件的路徑 * @param saveFile 保存的路徑 * @param rootPath 根目錄 * @return */ public synchronized static File download(String downloadFile, String saveFile, String rootPath) { boolean result = false; File file = null; Integer i = 0; while (!result) { FileOutputStream fileOutputStream = null; log.info("sftp file download start, target filepath is {}, save filepath is {}", downloadFile, saveFile); try { //獲取連接、讀取文件(ChannelSftp) session.openChannel("sftp") client.cd(rootPath); file = new File(saveFile); if (file.exists()) { file.delete(); } else { file.createNewFile(); } fileOutputStream = new FileOutputStream(file); client.get(downloadFile, fileOutputStream); result = true; } catch (FileNotFoundException e) { log.error("sftp file download fail, FileNotFound: [{}]", e.getMessage()); } catch (IOException e) { log.error("sftp file download fail, IOException: [{}]", e.getMessage()); } catch (SftpException e) { i++; log.error("sftp file download fail, sftpException: [{}]", e.getMessage()); if (i > DOWNLOAD_RETRY) { log.error("sftp file download fail, retry three times, SftpException: [{}]", e.getMessage()); return file; } try { TimeUnit.MILLISECONDS.sleep(DOWNLOAD_SLEEP); } catch (InterruptedException ex) { ex.printStackTrace(); } } finally { try { if (fileOutputStream != null) { fileOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } return file; } }
4.實際調用
public class SFTP { @Value("${sftp.ip}") String ip; @Value("${sftp.port}") Integer port; @Value("${sftp.username}") String username; @Value("${sftp.password}") String password; @Value("${sftp.root}") String rootPath; @GetMapping("/test") public void test() throws IOException { SFTPUtil.getInstance().makeConnection(username, password, ip, port); File file= SFTPUtil.download(downloadFilePath, "1.txt", rootPath); SFTPUtil.close(); InputStreamReader read = null; BufferedReader bufferedReader = null; String encoding = "utf-8"; try { read = new InputStreamReader(new FileInputStream(file), encoding); bufferedReader = new BufferedReader(read); String lineTxt = null; while ((lineTxt = bufferedReader.readLine()) != null) { log.info("[{}] downfile is [{}] ", username, lineTxt); } read.close(); bufferedReader.close(); file.delete(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (read != null) { read.close(); } if (bufferedReader != null) { bufferedReader.close(); } if (file != null && file.exists()) { file.delete(); } } catch (IOException e) { e.printStackTrace(); } } } }
springboot使用SFTP文件上傳
最近在工作功能使用瞭sftp做文件上傳下載的功能,在這裡簡單的記錄一下
pom文件中引入相關的jar包
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch --> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
建立springboot項目,在application.properties添加如下配置
sftp.ip=127.0.0.1 sftp.port=22 sftp.username=xuyy sftp.password=paswpord #ftp根目錄 sftp.rootpath="D:SFTP/
上面一sftp開頭的都是自定義配置,需要寫個配置類讀取一下,自動註入到springboot中
package com.uinnova.ftpsynweb.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 特點: 讀取配置文件。可以對靜態變量直接賦值 * * @author xuyangyang */ @Component @ConfigurationProperties(prefix = "sftp") @Data public class SftpConfig { public static String ip; public static Integer port; public static String username; public static String password; public static String rootpath; //註意這裡是 static 修飾,便於sftputil直接取值 public static String getIp() { return ip; } public void setIp(String ip) { SftpConfig.ip = ip; } public static Integer getPort() { return port; } public void setPort(Integer port) { SftpConfig.port = port; } public static String getUsername() { return username; } public void setUsername(String username) { SftpConfig.username = username; } public static String getPassword() { return password; } public void setPassword(String password) { SftpConfig.password = password; } public static String getRootpath() { return rootpath; } public void setRootpath(String rootpath) { SftpConfig.rootpath = rootpath; } }
下面是具體的工具類,代碼寫的比較簡單,可以自己下載優化一下,等我有時間在優化
package com.uinnova.ftpsynweb.util; import com.jcraft.jsch.*; import com.uinnova.ftpsynweb.config.SftpConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thymeleaf.util.StringUtils; import javax.transaction.SystemException; import java.io.*; import java.util.*; /** * SFTP工具類 */ @Slf4j @Component public class SftpUtil { @Autowired SftpConfig sftpConfig; private static String sftp_ip = SftpConfig.getIp(); private static Integer sftp_port = SftpConfig.getPort(); private static String sftp_username = SftpConfig.getUsername(); private static String sftp_password = SftpConfig.getPassword(); /** * sftp存儲根目錄 */ public static String windows_path = "D:SFTP/"; public static String linux_path = "/home/xuyy/"; private Session session; private ChannelSftp channel; /** * 規避多線程並發不斷開問題 */ private volatile static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<>(); private SftpUtil() { } private SftpUtil(String host, Integer port, String username, String password) { super(); init(host, port, username, password); } /** * 獲取本地線程存儲的sftp客戶端,使用玩必須調用 release()釋放連接 * * @return * @throws Exception */ public static SftpUtil getSftpUtil() { SftpUtil sftpUtil = sftpLocal.get(); if (null == sftpUtil || !sftpUtil.isConnected()) { sftpLocal.set(new SftpUtil(sftp_ip, sftp_port, sftp_username, sftp_password)); } return sftpLocal.get(); } /** * 獲取本地線程存儲的sftp客戶端,使用玩必須調用 release()釋放連接 * * @param host * @param port * @param username * @param password * @return */ public static SftpUtil getSftpUtil(String host, Integer port, String username, String password) { SftpUtil sftpUtil = sftpLocal.get(); if (null == sftpUtil || !sftpUtil.isConnected()) { log.info("建立連接"); sftpLocal.set(new SftpUtil(host, port, username, password)); } else { log.info("連接已經存在"); } return sftpLocal.get(); } /** * 初始化 創建一個新的 SFTP 通道 * * @param host * @param port * @param username * @param password */ private void init(String host, Integer port, String username, String password) { try { //場景JSch對象 JSch jSch = new JSch(); // jsch.addIdentity(); 私鑰 session = jSch.getSession(username, host, port); // 第一次登陸時候提示, (ask|yes|no) Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); config.put("compression.s2c", "zlib,none"); config.put("compression.c2s", "zlib,none"); session.setConfig(config); //設置超時 // session.setTimeout(10*1000); //設置密碼 session.setPassword(password); session.connect(); //打開SFTP通道 channel = (ChannelSftp) session.openChannel("sftp"); //建立SFTP通道的連接 channel.connect(); // 失敗重試2次 失敗不管瞭,隻發送一次 失敗回復 並行調用所有節點 } catch (JSchException e) { log.error("init話sftp異常,可能是獲得連接錯誤,請檢查用戶名密碼或者重啟sftp服務" + e); } } /** * 是否已連接 * * @return */ private boolean isConnected() { return null != channel && channel.isConnected(); } /** * 關閉通道 */ public void closeChannel() { if (null != channel) { try { channel.disconnect(); } catch (Exception e) { log.error("關閉SFTP通道發生異常:", e); } } if (null != session) { try { session.disconnect(); } catch (Exception e) { log.error("SFTP關閉 session異常:", e); } } } /** * 每次連接必須釋放資源,類似OSS服務 * 釋放本地線程存儲的sftp客戶端 */ public static void release() { if (null != sftpLocal.get()) { sftpLocal.get().closeChannel(); sftpLocal.set(null); } } /** * 列出目錄下文件,隻列出文件名字,沒有類型 * * @param dir 目錄 * @return */ public List list(String dir) { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問"); return null; } Vector<ChannelSftp.LsEntry> files = null; try { files = channel.ls(dir); } catch (SftpException e) { log.error(e.getMessage()); } if (null != files) { List fileNames = new ArrayList<String>(); Iterator<ChannelSftp.LsEntry> iter = files.iterator(); while (iter.hasNext()) { String fileName = iter.next().getFilename(); if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) { continue; } fileNames.add(fileName); } return fileNames; } return null; } /** * 列出文件詳情 * * @param dir * @return */ public List listDetail(String dir) { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問"); return null; } Vector<ChannelSftp.LsEntry> files = null; try { files = channel.ls(dir); } catch (SftpException e) { log.error("listDetail 獲取目錄列表 channel.ls " + dir + "失敗 " + e); } if (null != files) { List<Map<String, String>> fileList = new ArrayList<>(); Iterator<ChannelSftp.LsEntry> iter = files.iterator(); while (iter.hasNext()) { ChannelSftp.LsEntry next = iter.next(); Map<String, String> map = new HashMap<>(); String fileName = next.getFilename(); if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) { continue; } String size = String.valueOf(next.getAttrs().getSize()); long mtime = next.getAttrs().getMTime(); String type = ""; String longname = String.valueOf(next.getLongname()); if (longname.startsWith("-")) { type = "file"; } else if (longname.startsWith("d")) { type = "dir"; } map.put("name", fileName); map.put("size", size); map.put("type", type); map.put("mtime", DateTimeUtil.timestampToDate(mtime)); fileList.add(map); } return fileList; } return null; } /** * 遞歸獲得文件path下所有文件列表 * * @param path * @param list * @return * @throws SftpException */ public List<String> listOfRecursion(String path, List<String> list) throws SftpException { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問"); return null; } Vector<ChannelSftp.LsEntry> files = null; files = channel.ls(path); for (ChannelSftp.LsEntry entry : files) { if (!entry.getAttrs().isDir()) { String str = path + "/" + entry.getFilename(); str = str.replace("//", "/"); list.add(str); } else { if (!entry.getFilename().equals(".") && !entry.getFilename().equals("..")) { listOfRecursion(path + "/" + entry.getFilename(), list); } } } log.debug(list.toString()); return list; } /** * @param file 上傳文件 * @param remotePath 服務器存放路徑,支持多級目錄 * @throws SystemException */ public void upload(File file, String remotePath) throws SystemException { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問"); } FileInputStream fileInputStream = null; try { if (file.isFile()) { String rpath = remotePath;//服務器要創建的目錄 try { createDir(rpath); } catch (Exception e) { throw new SystemException("創建路徑失敗:" + rpath); } channel.cd(remotePath); System.out.println(remotePath); fileInputStream = new FileInputStream(file); channel.put(fileInputStream, file.getName()); } } catch (FileNotFoundException e) { throw new SystemException("上傳文件沒有找到"); } catch (SftpException e) { throw new SystemException("上傳ftp服務器錯誤"); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * @param file 上傳文件 * @param remoteName 上傳文件名字 * @param remotePath 服務器存放路徑,支持多級目錄 * @throws SystemException */ public boolean upload(File file, String remoteName, String remotePath) { if (channel == null) { System.out.println("get sftp connect fail,please reboot sftp client"); log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問"); } else { FileInputStream fileInputStream = null; try { if (file.isFile()) { //服務器要創建的目錄 String rpath = remotePath; createDir(rpath); channel.cd(remotePath); log.error(remotePath + " " + remoteName); fileInputStream = new FileInputStream(file); channel.put(fileInputStream, remoteName); return true; } } catch (FileNotFoundException e) { log.error("上傳文件沒有找到", e.getMessage()); return false; } catch (SftpException e) { log.error("upload" + remotePath + e); return false; } finally { try { if (fileInputStream != null) { fileInputStream.close();//這裡要關閉文件流 } else { log.error("流不存在" + remotePath + " " + remoteName); } } catch (IOException e) { e.printStackTrace(); } // try to delete the file immediately // boolean deleted = false; // try { // deleted = file.delete(); // } catch (SecurityException e) { // log.error(e.getMessage()); // } // // else delete the file when the program ends // if (deleted) { // System.out.println("Temp file deleted."); // log.info("Temp file deleted."); // } else { // file.deleteOnExit(); // System.out.println("Temp file scheduled for deletion."); // log.info("Temp file scheduled for deletion."); // } } } return false; } public boolean upload(InputStream inputStream, String remoteName, String remotePath) { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問"); } else { try { //服務器要創建的目錄 String rpath = remotePath; createDir(rpath); channel.cd(remotePath); log.debug(remotePath + " " + remoteName); channel.put(inputStream, remoteName); return true; } catch (SftpException e) { log.error("upload路徑不存在" + remotePath + e); return false; } finally { try { if (inputStream != null) { inputStream.close();//這裡要關閉文件流 } else { log.error("流不存在" + remotePath + " " + remoteName); } } catch (IOException e) { log.error(e.getMessage()); } // try to delete the file immediately // boolean deleted = false; // try { // deleted = file.delete(); // } catch (SecurityException e) { // log.error(e.getMessage()); // } // // else delete the file when the program ends // if (deleted) { // System.out.println("Temp file deleted."); // log.info("Temp file deleted."); // } else { // file.deleteOnExit(); // System.out.println("Temp file scheduled for deletion."); // log.info("Temp file scheduled for deletion."); // } } } return false; } /** * 下載文件 * * @param rootDir * @param filePath * @return */ public File downFile(String rootDir, String filePath) { if (channel == null) { log.error("獲取sftp連接失敗,請檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問"); return null; } OutputStream outputStream = null; File file = null; try { channel.cd(rootDir); String folder = System.getProperty("java.io.tmpdir"); file = new File(folder + File.separator + filePath.substring(filePath.lastIndexOf("/") + 1)); // file = new File(filePath.substring(filePath.lastIndexOf("/") + 1)); outputStream = new FileOutputStream(file); channel.get(filePath, outputStream); } catch (SftpException e) { log.error("downFile" + filePath + e); file = null; } catch (FileNotFoundException e) { log.error("FileNotFoundException", e); file = null; } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return file; } /** * 創建一個文件目錄 */ public void createDir(String createpath) { try { if (isDirExist(createpath)) { this.channel.cd(createpath); return; } String pathArry[] = createpath.split("/"); StringBuffer filePath = new StringBuffer("/"); for (String path : pathArry) { if (path.equals("")) { continue; } filePath.append(path + "/"); if (isDirExist(filePath.toString())) { channel.cd(filePath.toString()); } else { // 建立目錄 channel.mkdir(filePath.toString()); // 進入並設置為當前目錄 channel.cd(filePath.toString()); } } this.channel.cd(createpath); } catch (SftpException e) { log.error("createDir" + createpath + e); } } /** * 判斷目錄是否存在 */ public boolean isDirExist(String directory) { boolean isDirExistFlag = false; try { SftpATTRS sftpATTRS = channel.lstat(directory); isDirExistFlag = true; return sftpATTRS.isDir(); } catch (Exception e) { if (e.getMessage().toLowerCase().equals("no such file")) { isDirExistFlag = false; } } return isDirExistFlag; } static String PS = "/"; /** * This method is called recursively to download the folder content from SFTP server * * @param sourcePath * @param destinationPath * @throws SftpException */ public void recursiveFolderDownload(String sourcePath, String destinationPath) throws SftpException { Vector<ChannelSftp.LsEntry> fileAndFolderList = channel.ls(sourcePath); // Let list of folder content //Iterate through list of folder content for (ChannelSftp.LsEntry item : fileAndFolderList) { if (!item.getAttrs().isDir()) { // Check if it is a file (not a directory). if (!(new File(destinationPath + PS + item.getFilename())).exists() || (item.getAttrs().getMTime() > Long .valueOf(new File(destinationPath + PS + item.getFilename()).lastModified() / (long) 1000) .intValue())) { // Download only if changed later. new File(destinationPath + PS + item.getFilename()); channel.get(sourcePath + PS + item.getFilename(), destinationPath + PS + item.getFilename()); // Download file from source (source filename, destination filename). } } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) { new File(destinationPath + PS + item.getFilename()).mkdirs(); // Empty folder copy. recursiveFolderDownload(sourcePath + PS + item.getFilename(), destinationPath + PS + item.getFilename()); // Enter found folder on server to read its contents and create locally. } } } /** * 文件夾不存在,創建 * * @param folder 待創建的文件節夾 */ public void createFolder(String folder) { SftpATTRS stat = null; try { stat = channel.stat(folder); } catch (SftpException e) { log.error("復制目的地文件夾" + folder + "不存在,創建"); } if (stat == null) { try { channel.mkdir(folder); } catch (SftpException e) { log.error("創建失敗", e.getCause()); } } } public InputStream get(String filePath) { InputStream inputStream = null; try { inputStream = channel.get(filePath); } catch (SftpException e) { log.error("get" + e); } return inputStream; } public void put(InputStream inputStream, String filePath) { try { channel.put(inputStream, filePath); } catch (SftpException e) { log.error("put" + e); } } public Vector<ChannelSftp.LsEntry> ls(String filePath) { Vector ls = null; try { ls = channel.ls(filePath); } catch (SftpException e) { log.error("ls" + e); } return ls; } /** * 復制文件夾 * * @param src 源文件夾 * @param desc 目的文件夾 */ public void copy(String src, String desc) { // 檢查目的文件存在與否,不存在則創建 this.createDir(desc); // 查看源文件列表 Vector<ChannelSftp.LsEntry> fileAndFolderList = this.ls(src); for (ChannelSftp.LsEntry item : fileAndFolderList) { if (!item.getAttrs().isDir()) {//是一個文件 try (InputStream tInputStream = this.get(src + PS + item.getFilename()); ByteArrayOutputStream baos = new ByteArrayOutputStream() ) { byte[] buffer = new byte[1024]; int len; while ((len = tInputStream.read(buffer)) > -1) { baos.write(buffer, 0, len); } baos.flush(); InputStream nInputStream = new ByteArrayInputStream(baos.toByteArray()); this.put(nInputStream, desc + PS + item.getFilename()); } catch (IOException e) { log.error(e.getMessage()); } // 排除. 和 .. } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) { // 創建文件,可能不需要 this.createFolder(desc + PS + item.getFilename()); //遞歸復制文件 copy(src + PS + item.getFilename(), desc + PS + item.getFilename()); } } } /** * 刪除指定目錄文件 * * @param filePath 刪除文件路徑 * @return */ public Boolean del(String filePath) { boolean flag = false; try { channel.rm(filePath); flag = true; } catch (SftpException e) { flag = false; log.error("刪除文件錯誤報告: " + e); } return flag; } }
下面是具體的幾個接口,這裡也貼出來瞭,方便大傢使用
@Slf4j @RestController public class FileController { /** * @param file 上傳文件 * @param targetPath 保存文件路徑 * @param fileName 上傳文件名字 * @return * @throws IOException */ @RequestMapping(value = "/file/upload") @ResponseBody public Return upload(@RequestParam("file") MultipartFile file, String targetPath, String fileName) throws IOException { log.debug("上傳文件原始名字:" + file.getOriginalFilename() + "上傳路徑:" + targetPath + "上傳文件名: " + fileName); InputStream uploadFile = file.getInputStream(); SftpUtil sftpUtil = SftpUtil.getSftpUtil(); boolean upload = false; if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { upload = sftpUtil.upload(uploadFile, fileName, targetPath); } else { upload = sftpUtil.upload(uploadFile, fileName, SftpConfig.getRootpath() + targetPath); } SftpUtil.release(); return Return.Ok(upload); } /** * 需要下載的文件具體路徑 * * @param targetPath * @param response * @return * @throws UnsupportedEncodingException */ @RequestMapping(value = "/file/download") @ResponseBody public void download(String targetPath, HttpServletResponse response) throws UnsupportedEncodingException { log.debug("下載文件名字" + targetPath); // targetPath = new String(targetPath.getBytes("ISO8859-1"), "UTF-8"); if (StringUtils.isEmpty(targetPath) || !targetPath.contains("/")) { log.error("下載路徑不正確" + targetPath); // return Return.Fail("下載路徑不正確"); } String fileName = targetPath.substring(targetPath.lastIndexOf("/") + 1); log.debug(fileName); File file = null; SftpUtil sftpUtil = SftpUtil.getSftpUtil(); if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { file = sftpUtil.downFile("/", targetPath); } else { file = sftpUtil.downFile("/", SftpConfig.getRootpath() + targetPath); } SftpUtil.release(); if (!Objects.isNull(file)) { // 配置文件下載 response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); // 下載文件能正常顯示中文 // response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1")); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); byte[] buffer = new byte[1024]; FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream(file); bis = new BufferedInputStream(fis); OutputStream os = response.getOutputStream(); int i = bis.read(buffer); while (i != -1) { os.write(buffer, 0, i); i = bis.read(buffer); } // return Return.Ok("下載成功"); } catch (Exception e) { log.error("down fail" + e); // return Return.Fail("下載失敗"); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { log.error("down fail" + e); } } if (fis != null) { try { fis.close(); } catch (IOException e) { log.error("down fail" + e); } } } } // return Return.Fail("下載失敗"); } /** * 獲取sftp下文件消息列表 * * @param filePath 文件路徑 * @return */ @RequestMapping(value = "/file/list") @ResponseBody public Return list(@RequestParam("filePath") String filePath) { log.debug("獲取路徑下列表 :{}", filePath); SftpUtil sftpUtil = SftpUtil.getSftpUtil(); List<String> list = new ArrayList(); if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { list = sftpUtil.listDetail(filePath); } else { list = sftpUtil.listDetail(SftpConfig.getRootpath() + filePath); } SftpUtil.release(); return Return.Ok(list); } /** * 遞歸獲得文件path下所有文件列表 * * @param filePath 文件路徑 * @return */ @RequestMapping(value = "/file/listOfRecursion") @ResponseBody public Return listOfRecursion(@RequestParam("filePath") String filePath) { log.debug("獲取路徑下列表 :{}", filePath); SftpUtil sftpUtil = SftpUtil.getSftpUtil(); ArrayList<String> strings = new ArrayList<>(); Return ret = null; List<String> list; List<String> list1 = new ArrayList<>(); try { if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { list = sftpUtil.listOfRecursion(filePath, strings); ret = Return.Ok(list); } else { list = sftpUtil.listOfRecursion(SftpConfig.getRootpath() + filePath, strings); for (String str : list) { str = StringUtils.substring(str, SftpConfig.getRootpath().length() - 1); list1.add(str); } ret = Return.Ok(list1); } } catch (SftpException e) { log.error("listOfRecursion 獲取目錄列表 channel.ls " + filePath + "失敗 " + e); SftpUtil.release(); ret = Return.Fail(e.getMessage()); }finally { SftpUtil.release(); } return ret; } /** * sftp內復制文件夾 * * @param src 源文件夾 * @param desc 目的文件夾 * @return */ @RequestMapping(value = "file/copy") @ResponseBody public Return copy(String src, String desc) { SftpUtil sftpUtil = SftpUtil.getSftpUtil(); if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { sftpUtil.copy(src, desc); } else { sftpUtil.copy(SftpConfig.getRootpath() + src, SftpConfig.getRootpath() + desc); } SftpUtil.release(); return Return.Ok("復制成功"); } /** * 刪除文件 文件存在返回true ,文件不存在或刪除失敗返回 false * * @param filePath * @return */ @RequestMapping(value = "file/del") @ResponseBody public Return del(String filePath) { log.debug("刪除此文件 :{}", filePath); Boolean flag = false; SftpUtil sftpUtil = SftpUtil.getSftpUtil(); if (SftpConfig.WIN.equals(SftpConfig.getEnv())) { flag = sftpUtil.del(filePath); } else { flag = sftpUtil.del(SftpConfig.getRootpath() + filePath); } SftpUtil.release(); return new Return(flag, flag ? "刪除成功" : "文件不存在或刪除失敗"); } }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- JSch教程使用sftp協議實現服務器文件載操作
- Java使用Sftp和Ftp實現對文件的上傳和下載
- Linux雲服務器搭建SFTP服務器圖片服務器的操作
- SpringBoot集成SFTP客戶端實現文件上傳下載實例
- springboot2.1.3配置sftp自定義sftp連接池的詳細過程