SSHD实践(二)基于文件系统操作远程文件
Sftpadmin 发布于:2023-11-25 22:18:13
阅读:loading
前面介绍了使用Apache Mina SSHD的ChannelSftp实现对远程文件的操作,本文继续实践SSHD的系列文章,使用SftpFileSystem来实现对远程文件的操作。
Apache Mina SSHD中的ChannelSftp和SftpFileSystem都可以操作远程服务器的文件,但它们之间有一些区别:
(1)架构:ChannelSftp是基于SSH协议实现的SFTP协议的客户端,而SftpFileSystem是基于VFS(Virtual File System)框架的实现,可以通过多种协议(包括SFTP)访问远程文件系统。
(2)使用方式:ChannelSftp通过创建一个SFTP通道与远程服务器进行通信,直接发送SFTP指令来对远程文件进行操作,如上传、下载、删除等。而SftpFileSystem通过创建一个文件系统对象,并通过提供的API来访问和操作远程文件,类似于使用本地文件系统相同的方式。
(3)功能扩展:由于SftpFileSystem是基于VFS框架,可以通过配置支持多种文件系统和文件协议,如SFTP、FTP、HTTP等。它还提供了更高级的功能,例如目录监听、文件缓存等,可以更方便地进行文件操作。
总的来说,ChannelSftp更加轻量级和直接,适合简单的SFTP文件操作;而SftpFileSystem则更加灵活和可扩展,适合复杂的文件系统操作,并且可以支持多种协议。选择使用哪种方式可以根据具体的需求和使用场景进行选择。
SftpFileSystem是Apache Mina SSHD中实现的基于VFS框架的SFTP文件系统,具有以下特征:
(1)多协议支持:SftpFileSystem支持多种协议,包括SFTP、FTP、HTTP等。这使得它可以通过不同协议访问远程文件系统,并提供统一的API进行操作。
(2)高级功能支持:SftpFileSystem提供了一些额外的高级功能,例如目录监听和文件缓存。目录监听可以实现对远程目录的实时监控,当目录中的文件发生变化时,可以及时收到通知。文件缓存可以在本地缓存一部分远程文件,提高访问速度。
(3)与VFS集成:SftpFileSystem是基于VFS框架的实现,可以与VFS的其他功能进行集成。VFS提供了一些通用的文件系统操作API,如读取文件、写入文件、列出目录等,可以方便地在SftpFileSystem中使用。
(4)安全性:由于基于SSH协议,SftpFileSystem提供了安全的文件传输和身份验证机制。通过SSH的加密通信,可以保障数据的安全性。
(5)可扩展性:由于基于VFS框架,SftpFileSystem可以方便扩展支持其他协议和文件系统。可以通过定制来满足特定的需求,例如支持其他文件存储系统或加密算法等。
总的来说,SftpFileSystem提供了一套统一的API和一些额外的高级功能,方便用户访问和操作远程文件系统。它具有灵活性和可扩展性,适用于复杂的文件系统操作和要求更高级功能的场景。
package cn.chendd.sshd;
import ...;
/**
* Exec Test
*
* @author chendd
* @date 2023/11/20 19:10
*/
@RunWith(JUnit4.class)
public class SftpFileSystemTest {
/**
* 文件信息获取
*/
@Test
public void fileTest() throws IOException {
function((sshClient, session, fileSystem) -> {
final SftpPath path = fileSystem.getPath("/app/arthas/arthas-class/nohup.out");
System.out.println("文件名称:" + path.getFileName());
System.out.println("文件大小:" + Files.size(path));
//注:因时区差异需要设置小时+8
System.out.println("最后更新时间:" + Files.getLastModifiedTime(path));
System.out.println("文件权限:" + PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
});
}
/**
* 文件夹信息获取
*/
@Test
public void folderTest() throws IOException {
function((sshClient, session, fileSystem) -> {
final SftpPath defaultDir = fileSystem.getDefaultDir();
System.out.println("获取系统默认文件夹:" + defaultDir.toRealPath());
final SftpPath path = fileSystem.getPath("/app/arthas/arthas-class/");
System.out.println("文件夹名称:" + path.getFileName());
System.out.println("文件夹大小:" + Files.size(path));
//注:因时区差异需要设置小时+8
System.out.println("最后更新时间:" + Files.getLastModifiedTime(path));
System.out.println("文件夹权限:" + PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
System.out.println("=========================列出文件夹中全部======================");
try (final Stream<Path> stream = Files.list(path)) {
final List<Path> paths = stream.collect(Collectors.toList());
for (Path p : paths) {
if (Files.isDirectory(p)) {
System.out.println("文件夹:" + p.getFileName());
} else {
System.out.println("文件: " + p.getFileName());
}
}
}
System.out.println("=========================列出文件夹中全部======================");
});
}
/**
* 创建多层级文件夹目录
*/
@Test
public void mkdirsTest() throws IOException {
function((sshClient, session, fileSystem) -> {
final SftpPath path = fileSystem.getPath("/app/arthas/arthas-class/a/b/c/");
Files.createDirectories(path);
});
}
protected void function(Runnable runnable) throws IOException {
SshClient sshClient = SshClient.setUpDefaultClient();
sshClient.start();
SftpParam param = new SftpParam();
ClientSession session = sshClient.connect(param.getUsername(), param.getHost(), param.getPort()).verify().getSession();
session.addPasswordIdentity(param.getPassword());
session.auth().verify();
SftpFileSystem fileSystem = SftpClientFactory.instance().createSftpFileSystem(session);
runnable.run(sshClient , session , fileSystem);
fileSystem.close();
session.close();
sshClient.close();
}
@FunctionalInterface
protected interface Runnable {
void run(SshClient sshClient , ClientSession session , SftpFileSystem fileSystem) throws IOException;
}
//......省略上传、下载、删除等方法
}
(1)代码为示例,写的比较随意,某些IO资源的释放应以更严格的形式编写;
(2)示例实现了与ChannelSftp一样的全部实现:
① 文件上传;
② 文件下载;
③ 文件(夹)删除;
④ 文件(夹)重命名;
⑤ 文件(夹)路径是文件还是文件夹;
⑥ 文件夹路径创建;
⑦ 文件夹中的文件列表获取;
(1)本次实践Apache MINA SSHD共计四块知识,分别是使用Sftp访问远程服务器、Exec执行远程服务器命令、Shell执行远程服务器命令、SftpFileSystem,至于它还可以作用于的端口转发等功能不做摸索;
(2)本文实现了基于SSHD SftpFileSystem的文件的上传、下载、删除、重命名、文件列表、路径是否存在等多个常用的功能,完整示例代码可见《附件下载.zip》;
(3)工具类代码的封装像极了使用原生JDBC操作数据库的实现:① 每个方法都需要处理异常;② 每次操作都获取 Connection连接,使用完后关闭连接;
(4)工具类代码的封装应该以池化的形式,可以使用Apache Commons pool组件进行连接池的方式管理,在实际应用中将会更加科学;
点赞