All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.orion.remote.channel.sftp.SftpExecutor Maven / Gradle / Ivy

There is a newer version: 1.0.9
Show newest version
package com.orion.remote.channel.sftp;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.orion.constant.Const;
import com.orion.lang.StreamEntry;
import com.orion.remote.channel.BaseExecutor;
import com.orion.remote.channel.sftp.bigfile.SftpDownload;
import com.orion.remote.channel.sftp.bigfile.SftpUpload;
import com.orion.utils.Exceptions;
import com.orion.utils.Strings;
import com.orion.utils.Valid;
import com.orion.utils.collect.Lists;
import com.orion.utils.io.Files1;
import com.orion.utils.io.Streams;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;

/**
 * SFTP执行器
 * 

* 文件路必须是绝对路径 可以包含 ../ ./ * * @author Jiahang Li * @version 1.0.0 * @since 2020/10/7 19:52 */ public class SftpExecutor extends BaseExecutor { /** * 默认缓冲区大小 */ private int bufferSize; private ChannelSftp channel; /** * 根目录 */ private String home; /** * 编码格式 */ private String charset; public SftpExecutor(ChannelSftp channel) { this(channel, Const.UTF_8); } public SftpExecutor(ChannelSftp channel, String charset) { super(channel); Valid.notNull(charset, "charset is empty"); this.channel = channel; this.bufferSize = Const.BUFFER_KB_8; this.charset = charset; } @Override public SftpExecutor connect() { super.connect(); try { this.home = channel.getHome(); this.charset(charset); } catch (SftpException e) { throw Exceptions.sftp("read home path error", e); } return this; } @Override public SftpExecutor connect(int timeout) { super.connect(timeout); try { this.home = channel.getHome(); this.charset(charset); } catch (SftpException e) { throw Exceptions.sftp("read home path error", e); } return this; } @Override public void exec() { this.connect(); } /** * 设置缓冲区大小 * * @param bufferSize 缓冲区大小 * @return this */ public SftpExecutor bufferSize(int bufferSize) { this.bufferSize = bufferSize; return this; } /** * 设置文件名称编码格式 * * @param charset 编码格式 */ public void charset(String charset) { try { channel.setFilenameEncoding(charset); this.charset = charset; } catch (Exception e) { throw Exceptions.sftp("set sftp charset error", e); } } /** * 检查文件是否存在 * * @param path 文件绝对路径 * @return true 存在 */ public boolean isExist(String path) { try { channel.realpath(path); return true; } catch (Exception e) { return false; } } /** * 获取文件路径 * * @param path 文件绝对路径 * @return 文件绝对路径 null文件不存在 */ public String getPath(String path) { try { return channel.realpath(path); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return null; } else { throw Exceptions.sftp(e); } } } /** * 获取连接文件的源文件 * * @param path 连接文件的绝对路径 * @return 源文件的路径 null文件不是连接文件 */ public String getLinkPath(String path) { try { return channel.readlink(path); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return null; } else if (SftpErrorMessage.BAD_MESSAGE.getMessage().equalsIgnoreCase(e.getMessage())) { return null; } else { throw Exceptions.sftp(e); } } } /** * 获取文件属性 * * @param path 文件绝对路径 * @return 属性 */ public SftpFile getFile(String path) { return this.getFile(path, false); } /** * 获取文件属性 * * @param path 文件绝对路径 * @param followSymbolic 如果是连接文件是否返回原文件属性 * @return 属性 */ public SftpFile getFile(String path, boolean followSymbolic) { try { SftpATTRS attr; if (followSymbolic) { attr = channel.stat(path); } else { attr = channel.lstat(path); } return new SftpFile(path, attr); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return null; } else { throw Exceptions.sftp(e); } } } /** * 设置文件属性 * * @param attribute 文件属性 */ public void setFileAttribute(SftpFile attribute) { try { channel.setStat(attribute.getPath(), attribute.getAttrs()); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 设置文件修改时间 * * @param path 文件绝对路径 * @param date 修改时间 */ public void setModifyTime(String path, Date date) { try { channel.setMtime(path, (int) (date.getTime() / Const.MS_S_1)); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 修改文件权限 * * @param file 文件绝对路径 * @param permission 10进制表示的 8进制权限 如: 777 */ public void chmod(String file, int permission) { try { channel.chmod(Files1.permission10to8(permission), file); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 修改文件所有人 * * @param file 文件绝对路径 * @param uid 用户id */ public void chown(String file, int uid) { try { channel.chown(uid, file); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 修改文件所有组 * * @param file 文件绝对路径 * @param gid 组id */ public void chgrp(String file, int gid) { try { channel.chgrp(gid, file); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 清空文件, 没有则创建 * * @param path 文件绝对路径 */ public void truncate(String path) { try { this.touchTruncate(path); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return; } throw Exceptions.sftp(e); } } /** * 获取文件大小 如果不存在返回-1 * * @param path 文件绝对路径 * @return 文件大小 */ public long getSize(String path) { try { SftpFile attr = getFile(path, false); if (attr == null || attr.isDirectory()) { return -1; } return attr.getSize(); } catch (Exception e) { return -1; } } /** * 创建文件夹 * * @param path 文件夹绝对路径 */ public void mkdirs(String path) { SftpFile p = this.getFile(path, false); if (p != null && p.isDirectory()) { return; } List parentPaths = Files1.getParentPaths(path); parentPaths.add(path); boolean check = true; for (String parentPath : parentPaths) { if (check) { SftpFile parentAttr = this.getFile(parentPath, false); if (parentAttr == null || !parentAttr.isDirectory()) { check = false; } } if (!check) { try { channel.mkdir(parentPath); } catch (Exception e) { throw Exceptions.sftp(e); } } } } /** * 删除一个空的文件夹 * * @param path 绝对路径 */ public void rmdir(String path) { try { channel.rmdir(path); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return; } throw Exceptions.sftp(e); } } /** * 删除一个普通文件 * * @param path 绝对路径 */ public void rmFile(String path) { try { channel.rm(path); } catch (Exception e) { if (this.isNoSuchFileError(e)) { return; } throw Exceptions.sftp(e); } } /** * 递归删除文件或文件夹 * * @param path 路径 */ public void rm(String path) { try { SftpFile file = this.getFile(path); if (file == null) { return; } if (file.isDirectory()) { List files = this.ll(path); for (SftpFile f : files) { if (f.isDirectory()) { this.rm(f.getPath()); } else { channel.rm(f.getPath()); } } channel.rmdir(path); } else { channel.rm(path); } } catch (Exception e) { if (this.isNoSuchFileError(e)) { return; } throw Exceptions.sftp(e); } } /** * 创建文件 * * @param path 文件绝对路径 */ public void touch(String path) { this.touch(path, false); } /** * 创建文件 如果文件存在则截断 * * @param path 文件绝对路径 */ public void touchTruncate(String path) { touch(path, true); } /** * 创建文件 * * @param path 文件绝对路径 * @param truncate 如果文件存在是否截断 */ public void touch(String path, boolean truncate) { this.mkdirs(Files1.getParentPath(path)); try { OutputStream t; if (truncate) { t = this.getOutputStream(path, 0); } else { t = this.getOutputStream(path, 1); } t.flush(); Streams.close(t); } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 创建硬连接文件 * * @param source 原文件绝对路径 * @param target 新文件绝对路径 */ public void touchHardLink(String source, String target) { this.touchLink(source, target, true); } /** * 创建软连接文件 * * @param source 原文件绝对路径 * @param target 新文件绝对路径 */ public void touchSymLink(String source, String target) { this.touchLink(source, target, false); } /** * 创建连接文件 * * @param source 原文件绝对路径 * @param target 连接文件绝对路径 */ public void touchLink(String source, String target) { this.touchLink(source, target, false); } /** * 创建连接文件 * * @param source 原文件绝对路径 * @param target 连接文件绝对路径 * @param hard true硬链接 false软连接 */ public void touchLink(String source, String target, boolean hard) { try { this.mkdirs(Files1.getParentPath(target)); if (hard) { channel.hardlink(source, target); } else { channel.symlink(source, target); } } catch (Exception e) { throw Exceptions.sftp(e); } } /** * 移动文件 * * @param source 原文件绝对路径 * @param target 目标文件 绝对路径 相对路径都可以 */ public void mv(String source, String target) { try { source = Files1.getPath(source); target = Files1.getPath(target); if (target.charAt(0) == '/') { this.mkdirs(Files1.getParentPath(target)); channel.rename(source, Files1.normalize(target)); } else { channel.rename(source, Files1.normalize(Files1.getPath(source + "/../" + target))); } } catch (Exception e) { throw Exceptions.sftp(e); } } // -------------------- stream -------------------- public InputStream getInputStream(String path) throws IOException { return this.getInputStream(path, 0L); } /** * 打开存在文件的输入流 * * @param path 文件路径 * @param skip 跳过的字节 * @return InputStream * @throws IOException IOException */ public InputStream getInputStream(String path, long skip) throws IOException { try { return channel.get(path, null, skip); } catch (Exception e) { throw Exceptions.io("could open file input stream " + path, e); } } public OutputStream getOutputStreamWriter(String path) throws IOException { return this.getOutputStream(path, 0); } public OutputStream getOutputStreamAppend(String path) throws IOException { return this.getOutputStream(path, 2); } /** * 打开存在文件的输出流 * * @param path 文件路径 * @param mode 0 完全覆盖模式 * 1 恢复模式 * 2 追加模式 * @return OutputStream * @throws IOException IOException */ public OutputStream getOutputStream(String path, int mode) throws IOException { try { this.mkdirs(Files1.getParentPath(path)); return channel.put(path, mode); } catch (Exception e) { throw Exceptions.io("could open file output stream " + path, e); } } // -------------------- read -------------------- public int read(String path, byte[] bs) throws IOException { return this.read(path, 0, bs, 0, bs.length); } public int read(String path, long skip, byte[] bs) throws IOException { return this.read(path, skip, bs, 0, bs.length); } public int read(String path, byte[] bs, int offset, int len) throws IOException { return this.read(path, 0, bs, offset, len); } /** * 读取文件 * * @param path 文件绝对路径 * @param skip 跳过字节数 * @param bs 字节数组 * @param offset offset * @param len len * @return read len * @throws IOException IOException */ public int read(String path, long skip, byte[] bs, int offset, int len) throws IOException { InputStream in = null; try { in = this.getInputStream(path, skip); return in.read(bs, offset, len); } finally { Streams.close(in); } } public String readLine(String path) throws IOException { return this.readLine(path, 0L); } /** * 读取一行 * * @param path path * @param skip skip * @return line * @throws IOException IOException */ public String readLine(String path, long skip) throws IOException { InputStream in = null; BufferedReader reader = null; try { in = this.getInputStream(path, skip); reader = new BufferedReader(new InputStreamReader(in, charset)); return reader.readLine(); } finally { Streams.close(in); Streams.close(reader); } } public List readLines(String path) throws IOException { return this.readLines(path, 0L, 0); } public List readLines(String path, long skip) throws IOException { return this.readLines(path, skip, 0); } public List readLines(String path, int lines) throws IOException { return this.readLines(path, 0L, lines); } /** * 读取多行 * * @param path path * @param skip skip * @param lines 行数 * @return lines * @throws IOException IOException */ public List readLines(String path, long skip, int lines) throws IOException { InputStream in = null; BufferedReader reader = null; try { in = this.getInputStream(path, skip); reader = new BufferedReader(new InputStreamReader(in, charset)); List list = new ArrayList<>(); String line; if (lines > 0) { for (int i = 0; i < lines && (line = reader.readLine()) != null; i++) { list.add(line); } } else { while ((line = reader.readLine()) != null) { list.add(line); } } return list; } finally { Streams.close(in); Streams.close(reader); } } // -------------------- transfer -------------------- public long transfer(String path, OutputStream out) throws IOException { return this.transfer(path, out, 0, -1); } public long transfer(String path, OutputStream out, long skip) throws IOException { return this.transfer(path, out, skip, -1); } public long transfer(String path, String file) throws IOException { Files1.touch(file); OutputStream out = null; try { return this.transfer(path, out = Files1.openOutputStream(file), 0, -1); } finally { Streams.close(out); } } public long transfer(String path, String file, long skip) throws IOException { Files1.touch(file); OutputStream out = null; try { return this.transfer(path, out = Files1.openOutputStream(file), skip, -1); } finally { Streams.close(out); } } public long transfer(String path, File file) throws IOException { Files1.touch(file); OutputStream out = null; try { return this.transfer(path, out = Files1.openOutputStream(file), 0, -1); } finally { Streams.close(out); } } public long transfer(String path, File file, long skip) throws IOException { Files1.touch(file); OutputStream out = null; try { return this.transfer(path, out = Files1.openOutputStream(file), skip, -1); } finally { Streams.close(out); } } /** * 读取字节到输出流 * * @param path 文件绝对路径 * @param out 输出流 * @param skip 跳过字数 * @param size 读取长度 -1 读取全部 * @return 已读取长度 * @throws IOException IOException */ public long transfer(String path, OutputStream out, long skip, int size) throws IOException { long r = 0; byte[] bs = new byte[this.bufferSize]; InputStream in = null; try { in = this.getInputStream(path, skip); if (size != -1) { boolean mod = size % this.bufferSize == 0; long readTimes = size / this.bufferSize; if (mod || readTimes == 0) { readTimes++; } for (int i = 0; i < readTimes; i++) { if (readTimes == 1) { int read = in.read(bs, 0, size); out.write(bs, 0, read); r += read; } else { int read = in.read(bs, 0, this.bufferSize); if (read != -1) { out.write(bs, 0, read); r += read; } else { break; } } } } else { int read; while ((read = in.read(bs, 0, this.bufferSize)) != -1) { out.write(bs, 0, read); r += read; } } } finally { Streams.close(in); } return r; } // -------------------- write -------------------- public void write(String path, InputStream in) throws IOException { this.write(path, in, null, null, 0); } public void write(String path, byte[] bs) throws IOException { this.write(path, null, new StreamEntry(bs), null, 0); } public void write(String path, byte[] bs, int off, int len) throws IOException { this.write(path, null, new StreamEntry(bs, off, len), null, 0); } public void writeLine(String path, String line) throws IOException { this.write(path, null, null, Lists.singleton(line), 0); } public void writeLines(String path, List lines) throws IOException { this.write(path, null, null, lines, 0); } // -------------------- append -------------------- public void append(String path, InputStream in) throws IOException { this.write(path, in, null, null, 2); } public void append(String path, byte[] bs) throws IOException { this.write(path, null, new StreamEntry(bs), null, 2); } public void append(String path, byte[] bs, int off, int len) throws IOException { this.write(path, null, new StreamEntry(bs, off, len), null, 2); } public void appendLine(String path, String line) throws IOException { this.write(path, null, null, Lists.singleton(line), 2); } public void appendLines(String path, List lines) throws IOException { this.write(path, null, null, lines, 2); } /** * 拼接/写入到文件 * * @param path 文件绝对路径 * @param in 输入流 * @param entry 写入信息 * @param lines 行 * @param mode 0 完全覆盖模式 * 1 恢复模式 如果文件正在传输时, 由于网络等原因导致传输中断, 则下一次传输相同的文件, 会从上一次中断的地方续传 * 2 追加模式 * @throws IOException IOException */ private void write(String path, InputStream in, StreamEntry entry, List lines, int mode) throws IOException { this.touch(path, mode == 0); OutputStream out = this.getOutputStream(path, mode); try { if (in != null) { byte[] bs = new byte[bufferSize]; int read; while ((read = in.read(bs)) != -1) { out.write(bs, 0, read); } } else if (entry != null) { out.write(entry.getBytes(), entry.getOff(), entry.getLen()); } else if (lines != null) { for (String line : lines) { out.write(Strings.bytes(line + Const.LF, charset)); } } out.flush(); } finally { Streams.close(out); } } // -------------------- upload -------------------- public void uploadFile(String remoteFile, String localFile) throws IOException { this.uploadFile(remoteFile, Files1.openInputStreamSafe(localFile), true); } public void uploadFile(String remoteFile, File localFile) throws IOException { this.uploadFile(remoteFile, Files1.openInputStreamSafe(localFile), true); } public void uploadFile(String remoteFile, InputStream in) throws IOException { this.uploadFile(remoteFile, in, false); } /** * 上传文件 * * @param remoteFile 远程文件 * @param in input * @param close close * @throws IOException IOException */ public void uploadFile(String remoteFile, InputStream in, boolean close) throws IOException { BufferedInputStream buffer = null; try { this.write(remoteFile, buffer = new BufferedInputStream(in, bufferSize)); } finally { if (close) { Streams.close(in); Streams.close(buffer); } } } public void uploadDir(String remoteDir, File localDir) throws IOException { this.uploadDir(remoteDir, localDir.getAbsolutePath(), true); } public void uploadDir(String remoteDir, String localDir) throws IOException { this.uploadDir(remoteDir, localDir, true); } public void uploadDir(String remoteDir, File localDir, boolean child) throws IOException { this.uploadDir(remoteDir, localDir.getAbsolutePath(), child); } /** * 上传文件夹 * * @param remoteDir 远程文件夹 * @param localDir 本地文件夹 上传时不包含此文件夹 * @param child 是否遍历上传 * @throws IOException IOException */ public void uploadDir(String remoteDir, String localDir, boolean child) throws IOException { localDir = Files1.getPath(localDir); List dirs = Files1.listDirs(localDir, child); List files = Files1.listFiles(localDir, child); for (File dir : dirs) { this.mkdirs(Files1.getPath(remoteDir, dir.getAbsolutePath().substring(localDir.length()))); } for (File file : files) { String path = Files1.getPath(remoteDir, file.getAbsolutePath().substring(localDir.length())); this.uploadFile(path, file); } } // -------------------- download -------------------- public void downloadFile(String remoteFile, String localFile) throws IOException { Files1.touch(localFile); this.downloadFile(remoteFile, Files1.openOutputStreamSafe(localFile), true); } public void downloadFile(String remoteFile, File localFile) throws IOException { Files1.touch(localFile); this.downloadFile(remoteFile, Files1.openOutputStreamSafe(localFile), true); } public void downloadFile(String remoteFile, OutputStream out) throws IOException { this.downloadFile(remoteFile, out, false); } /** * 下载文件 * * @param remoteFile 远程文件路径 * @param out output * @param close 是否自动关闭 * @throws IOException IOException */ public void downloadFile(String remoteFile, OutputStream out, boolean close) throws IOException { try { this.transfer(remoteFile, out); } finally { if (close) { Streams.close(out); } } } public void downloadDir(String remoteDir, File localDir) throws IOException { this.downloadDir(remoteDir, localDir.getAbsolutePath(), true); } public void downloadDir(String remoteDir, String localDir) throws IOException { this.downloadDir(remoteDir, localDir, true); } public void downloadDir(String remoteDir, File localDir, boolean child) throws IOException { this.downloadDir(remoteDir, localDir.getAbsolutePath(), child); } /** * 下载文件夹 * * @param remoteDir 远程文件夹 * @param localDir 本地文件夹 * @param child 是否递归子文件夹下载 * @throws IOException pending */ public void downloadDir(String remoteDir, String localDir, boolean child) throws IOException { remoteDir = Files1.getPath(remoteDir); if (!child) { List list = this.listFiles(remoteDir, false); for (SftpFile s : list) { this.downloadFile(s.getPath(), Files1.getPath(localDir, Files1.getFileName(s.getPath()))); } } else { List list = this.listDirs(remoteDir, true); for (SftpFile s : list) { Files1.mkdirs(Files1.getPath(localDir, s.getPath().substring(remoteDir.length()))); } list = this.listFiles(remoteDir, true); for (SftpFile s : list) { this.downloadFile(s.getPath(), Files1.getPath(localDir, s.getPath().substring(remoteDir.length()))); } } } // -------------------- big file -------------------- public SftpUpload upload(String remote, File local) { return new SftpUpload(this, remote, local); } /** * 获取文件上传器 * * @param remote 远程文件绝对路径 * @param local 本地文件 * @return 文件上传器 */ public SftpUpload upload(String remote, String local) { return new SftpUpload(this, remote, local); } public SftpDownload download(String remote, File local) { return new SftpDownload(this, remote, local); } /** * 获取文件下载器 * * @param remote 远程文件绝对路径 * @param local 本地文件 * @return 文件下载器 */ public SftpDownload download(String remote, String local) { return new SftpDownload(this, remote, local); } // -------------------- list -------------------- /** * 获取目录文件属性 * * @param path 文件绝对路径 * @return 属性 */ public List ll(String path) { List list = new ArrayList<>(); try { Vector files = channel.ls(path); for (Object l : files) { ChannelSftp.LsEntry ls = (ChannelSftp.LsEntry) l; String filename = ls.getFilename(); if (".".equals(filename) || "..".equals(filename)) { continue; } list.add(new SftpFile(Files1.getPath(path, filename), ls.getLongname(), ls.getAttrs())); } } catch (Exception e) { throw Exceptions.sftp(e); } return list; } public List listFiles(String path) { return this.listFiles(path, false, false); } public List listFiles(String path, boolean child) { return this.listFiles(path, child, false); } /** * 文件列表 * * @param path 文件夹绝对路径 * @param child 是否递归子文件夹 * @param dir 是否添加文件夹 * @return 文件列表 */ public List listFiles(String path, boolean child, boolean dir) { List list = new ArrayList<>(); try { List ls = this.ll(path); for (SftpFile l : ls) { if (l.isDirectory()) { if (dir) { list.add(l); } if (child) { list.addAll(this.listFiles(Files1.getPath(path, l.getName()), true, dir)); } } else { list.add(l); } } } catch (Exception e) { throw Exceptions.sftp(e); } return list; } public List listDirs(String path) { return this.listDirs(path, false); } /** * 文件夹列表 * * @param path 文件夹绝对路径 * @param child 是否递归 * @return 文件列表 */ public List listDirs(String path, boolean child) { List list = new ArrayList<>(); try { List ls = this.ll(path); for (SftpFile l : ls) { if (l.isDirectory()) { list.add(l); if (child) { list.addAll(this.listDirs(Files1.getPath(path, l.getName()), true)); } } } } catch (Exception e) { throw Exceptions.sftp(e); } return list; } public List listFilesSuffix(String path, String suffix) { return this.listFilesSuffix(path, suffix, false, false); } public List listFilesSuffix(String path, String suffix, boolean child) { return this.listFilesSuffix(path, suffix, child, false); } /** * 搜索文件 后缀 * * @param path 文件夹绝对路径 * @param suffix 后缀 * @param child 是否递归子文件夹 * @param dir 是否添加文件夹 * @return 文件 */ public List listFilesSuffix(String path, String suffix, boolean child, boolean dir) { return this.listFilesSearch(path, FileAttributeFilter.suffix(suffix), child, dir); } public List listFilesMatch(String path, String match) { return this.listFilesMatch(path, match, false, false); } public List listFilesMatch(String path, String match, boolean child) { return this.listFilesMatch(path, match, child, false); } /** * 搜索文件 文件名 * * @param path 文件夹绝对路径 * @param match 匹配 * @param child 是否递归子文件夹 * @param dir 是否添加文件夹 * @return 文件 */ public List listFilesMatch(String path, String match, boolean child, boolean dir) { return this.listFilesSearch(path, FileAttributeFilter.match(match), child, dir); } public List listFilesPattern(String path, Pattern pattern) { return this.listFilesPattern(path, pattern, false, false); } public List listFilesPattern(String path, Pattern pattern, boolean child) { return this.listFilesPattern(path, pattern, child, false); } /** * 搜索文件 正则 * * @param path 文件夹绝对路径 * @param pattern 正则 * @param child 是否递归子文件夹 * @param dir 是否添加文件夹 * @return 文件 */ public List listFilesPattern(String path, Pattern pattern, boolean child, boolean dir) { return this.listFilesSearch(path, FileAttributeFilter.pattern(pattern), child, dir); } public List listFilesFilter(String path, FileAttributeFilter filter) { return this.listFilesFilter(path, filter, false, false); } public List listFilesFilter(String path, FileAttributeFilter filter, boolean child) { return this.listFilesFilter(path, filter, child, false); } /** * 搜索文件 过滤器 * * @param path 文件夹绝对路径 * @param filter 过滤器 * @param child 是否递归子文件夹 * @param dir 是否添加文件夹 * @return 文件 */ public List listFilesFilter(String path, FileAttributeFilter filter, boolean child, boolean dir) { return this.listFilesSearch(path, filter, child, dir); } /** * 搜索文件 * * @param path 文件夹绝对路径 * @param filter 过滤器 * @param child 是否递归 * @param dir 是否添加文件夹 * @return 文件 */ private List listFilesSearch(String path, FileAttributeFilter filter, boolean child, boolean dir) { List list = new ArrayList<>(); try { List ls = this.ll(path); for (SftpFile l : ls) { String fn = l.getName(); boolean isDir = l.isDirectory(); if (!isDir || dir) { if (filter.accept(l)) { list.add(l); } } if (isDir && child) { list.addAll(this.listFilesSearch(Files1.getPath(path, fn), filter, true, dir)); } } } catch (Exception e) { throw Exceptions.sftp(e); } return list; } /** * 是否为未找到文件异常 * * @param e e * @return res */ private boolean isNoSuchFileError(Exception e) { String message = e.getMessage(); if (Strings.isEmpty(message)) { return false; } return message.toLowerCase().contains(SftpErrorMessage.NO_SUCH_FILE.getMessage()); } // -------------------- option -------------------- /** * 获取客户端版本 * * @return 客户端版本 */ public String getClientVersion() { return channel.version(); } /** * 获取服务端版本 * * @return 服务端版本 */ public int getServerVersion() { try { return channel.getServerVersion(); } catch (SftpException e) { throw Exceptions.sftp(e); } } @Override public void close() { channel.disconnect(); } @Override public ChannelSftp getChannel() { return channel; } public String getHome() { return home; } public int getBufferSize() { return bufferSize; } public String getCharset() { return charset; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy