springboot如何讀取sftp的文件
springboot讀取sftp的文件
1.添加pom依賴(基于springboot項(xiàng)目)
<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 {
/**
* 下載重試次數(shù)
*/
private static final int DOWNLOAD_RETRY = 3;
/**
* 下載重試間隔時(shí)間 單位毫秒
*/
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();
// 設(shè)置第一次登陸的時(shí)候主機(jī)公鑰確認(rèn)提示,可選值:(ask | yes | no)
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
//sftp協(xié)議
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;
}
/**
*
* 關(guān)閉連接 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 主機(jī)地址
* @param port 主機(jī)端口
* @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.實(shí)際調(diào)用
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做文件上傳下載的功能,在這里簡(jiǎn)單的記錄一下
pom文件中引入相關(guān)的jar包
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
建立springboot項(xiàng)目,在application.properties添加如下配置
sftp.ip=127.0.0.1 sftp.port=22 sftp.username=xuyy sftp.password=paswpord #ftp根目錄 sftp.rootpath="D:SFTP/
上面一sftp開(kāi)頭的都是自定義配置,需要寫(xiě)個(gè)配置類讀取一下,自動(dòng)注入到springboot中
package com.uinnova.ftpsynweb.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 特點(diǎn): 讀取配置文件??梢詫?duì)靜態(tài)變量直接賦值
*
* @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;
}
}
下面是具體的工具類,代碼寫(xiě)的比較簡(jiǎn)單,可以自己下載優(yōu)化一下,等我有時(shí)間在優(yōu)化
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存儲(chǔ)根目錄
*/
public static String windows_path = "D:SFTP/";
public static String linux_path = "/home/xuyy/";
private Session session;
private ChannelSftp channel;
/**
* 規(guī)避多線程并發(fā)不斷開(kāi)問(wèn)題
*/
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);
}
/**
* 獲取本地線程存儲(chǔ)的sftp客戶端,使用玩必須調(diào)用 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();
}
/**
* 獲取本地線程存儲(chǔ)的sftp客戶端,使用玩必須調(diào)用 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("連接已經(jīng)存在");
}
return sftpLocal.get();
}
/**
* 初始化 創(chuàng)建一個(gè)新的 SFTP 通道
*
* @param host
* @param port
* @param username
* @param password
*/
private void init(String host, Integer port, String username, String password) {
try {
//場(chǎng)景JSch對(duì)象
JSch jSch = new JSch();
// jsch.addIdentity(); 私鑰
session = jSch.getSession(username, host, port);
// 第一次登陸時(shí)候提示, (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);
//設(shè)置超時(shí)
// session.setTimeout(10*1000);
//設(shè)置密碼
session.setPassword(password);
session.connect();
//打開(kāi)SFTP通道
channel = (ChannelSftp) session.openChannel("sftp");
//建立SFTP通道的連接
channel.connect();
// 失敗重試2次 失敗不管了,只發(fā)送一次 失敗回復(fù) 并行調(diào)用所有節(jié)點(diǎn)
} catch (JSchException e) {
log.error("init話sftp異常,可能是獲得連接錯(cuò)誤,請(qǐng)檢查用戶名密碼或者重啟sftp服務(wù)" + e);
}
}
/**
* 是否已連接
*
* @return
*/
private boolean isConnected() {
return null != channel && channel.isConnected();
}
/**
* 關(guān)閉通道
*/
public void closeChannel() {
if (null != channel) {
try {
channel.disconnect();
} catch (Exception e) {
log.error("關(guān)閉SFTP通道發(fā)生異常:", e);
}
}
if (null != session) {
try {
session.disconnect();
} catch (Exception e) {
log.error("SFTP關(guān)閉 session異常:", e);
}
}
}
/**
* 每次連接必須釋放資源,類似OSS服務(wù)
* 釋放本地線程存儲(chǔ)的sftp客戶端
*/
public static void release() {
if (null != sftpLocal.get()) {
sftpLocal.get().closeChannel();
sftpLocal.set(null);
}
}
/**
* 列出目錄下文件,只列出文件名字,沒(méi)有類型
*
* @param dir 目錄
* @return
*/
public List list(String dir) {
if (channel == null) {
log.error("獲取sftp連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問(wèn)");
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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問(wèn)");
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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問(wèn)");
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("http://", "/");
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 服務(wù)器存放路徑,支持多級(jí)目錄
* @throws SystemException
*/
public void upload(File file, String remotePath) throws SystemException {
if (channel == null) {
log.error("獲取sftp連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問(wèn)");
}
FileInputStream fileInputStream = null;
try {
if (file.isFile()) {
String rpath = remotePath;//服務(wù)器要?jiǎng)?chuàng)建的目錄
try {
createDir(rpath);
} catch (Exception e) {
throw new SystemException("創(chuàng)建路徑失敗:" + rpath);
}
channel.cd(remotePath);
System.out.println(remotePath);
fileInputStream = new FileInputStream(file);
channel.put(fileInputStream, file.getName());
}
} catch (FileNotFoundException e) {
throw new SystemException("上傳文件沒(méi)有找到");
} catch (SftpException e) {
throw new SystemException("上傳ftp服務(wù)器錯(cuò)誤");
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* @param file 上傳文件
* @param remoteName 上傳文件名字
* @param remotePath 服務(wù)器存放路徑,支持多級(jí)目錄
* @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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問(wèn)");
} else {
FileInputStream fileInputStream = null;
try {
if (file.isFile()) {
//服務(wù)器要?jiǎng)?chuàng)建的目錄
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("上傳文件沒(méi)有找到", e.getMessage());
return false;
} catch (SftpException e) {
log.error("upload" + remotePath + e);
return false;
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();//這里要關(guān)閉文件流
} 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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問(wèn)");
} else {
try {
//服務(wù)器要?jiǎng)?chuàng)建的目錄
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();//這里要關(guān)閉文件流
} 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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + " " + sftp_password + "是否可以訪問(wèn)");
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;
}
/**
* 創(chuàng)建一個(gè)文件目錄
*/
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());
// 進(jìn)入并設(shè)置為當(dāng)前目錄
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.
}
}
}
/**
* 文件夾不存在,創(chuàng)建
*
* @param folder 待創(chuàng)建的文件節(jié)夾
*/
public void createFolder(String folder) {
SftpATTRS stat = null;
try {
stat = channel.stat(folder);
} catch (SftpException e) {
log.error("復(fù)制目的地文件夾" + folder + "不存在,創(chuàng)建");
}
if (stat == null) {
try {
channel.mkdir(folder);
} catch (SftpException e) {
log.error("創(chuàng)建失敗", 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;
}
/**
* 復(fù)制文件夾
*
* @param src 源文件夾
* @param desc 目的文件夾
*/
public void copy(String src, String desc) {
// 檢查目的文件存在與否,不存在則創(chuàng)建
this.createDir(desc);
// 查看源文件列表
Vector<ChannelSftp.LsEntry> fileAndFolderList = this.ls(src);
for (ChannelSftp.LsEntry item : fileAndFolderList) {
if (!item.getAttrs().isDir()) {//是一個(gè)文件
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()))) {
// 創(chuàng)建文件,可能不需要
this.createFolder(desc + PS + item.getFilename());
//遞歸復(fù)制文件
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("刪除文件錯(cuò)誤報(bào)告: " + e);
}
return flag;
}
}
下面是具體的幾個(gè)接口,這里也貼出來(lái)了,方便大家使用
@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內(nèi)復(fù)制文件夾
*
* @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("復(fù)制成功");
}
/**
* 刪除文件 文件存在返回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 ? "刪除成功" : "文件不存在或刪除失敗");
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決RedisTemplate調(diào)用increment報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了解決RedisTemplate調(diào)用increment報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
詳細(xì)說(shuō)明關(guān)于Java的數(shù)據(jù)庫(kù)連接(JDBC)
這篇文章主要介紹了詳細(xì)說(shuō)明關(guān)于Java的數(shù)據(jù)庫(kù)連接JDBC,JDBC是用Java語(yǔ)言向數(shù)據(jù)庫(kù)發(fā)送SQL語(yǔ)句,需要的朋友可以參考下面文章內(nèi)容2021-09-09
Spring4.0 MVC請(qǐng)求json數(shù)據(jù)報(bào)406錯(cuò)誤的解決方法
這篇文章主要為大家詳細(xì)介紹了Spring4.0 MVC請(qǐng)求json數(shù)據(jù)報(bào)406錯(cuò)誤的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
idea運(yùn)行main方法或Test避免編譯整個(gè)應(yīng)用的實(shí)現(xiàn)方法
這篇文章主要介紹了idea運(yùn)行main方法或Test避免編譯整個(gè)應(yīng)用的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
java實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載功能的具體代碼,感興趣的小伙伴們可以參考一下2016-05-05
Java通過(guò)HttpClient進(jìn)行HTTP請(qǐng)求的代碼詳解
Apache?HttpClient是一個(gè)功能強(qiáng)大且廣泛使用的Java庫(kù),它提供了方便的方法來(lái)執(zhí)行HTTP請(qǐng)求并處理響應(yīng)。本文將介紹如何使用HttpClient庫(kù)進(jìn)行HTTP請(qǐng)求,包括GET請(qǐng)求、POST請(qǐng)求、添加參數(shù)和請(qǐng)求體、設(shè)置請(qǐng)求頭等操作,需要的朋友可以參考下2023-05-05
詳解Spring Boot Oauth2緩存UserDetails到Ehcache
這篇文章主要介紹了詳解Spring Boot Oauth2緩存UserDetails到Ehcache,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法
這篇文章主要介紹了idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
mall整合SpringSecurity及JWT認(rèn)證授權(quán)實(shí)戰(zhàn)下
這篇文章主要為大家介紹了mall整合SpringSecurity及JWT認(rèn)證授權(quán)實(shí)戰(zhàn)第二篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

