javascript
比较中的Commons VFS,SSHJ和JSch
幾周前,我評(píng)估了一些用于Java的SSH庫。 對(duì)它們的主要要求是在遠(yuǎn)程計(jì)算機(jī)上進(jìn)行文件傳輸和文件操作。 因此,它存在一個(gè)基于SSH,SSH文件傳輸協(xié)議(或SFTP)的網(wǎng)絡(luò)協(xié)議。 因此,我需要一個(gè)支持SFTP的SSH庫。
一項(xiàng)研究表明,它退出了許多用于Java的SSH庫。 為了進(jìn)行比較,我將庫的數(shù)量減少到三個(gè)。 我選擇JSch,SSHJ和Apache的Commons VFS,以獲得更深入的了解。 它們都支持SFTP。 JSch似乎是Java的實(shí)際標(biāo)準(zhǔn)。 SSHJ是較新的庫。 其目標(biāo)是為SSH提供一個(gè)清晰的Java API。 它在后臺(tái)使用Apache SSHD。 Commons VFS的目標(biāo)是為虛擬文件系統(tǒng)提供清晰的API,SFTP是受支持的協(xié)議之一。 在后臺(tái),它將JSch用于SFTP協(xié)議。 這些庫應(yīng)滿足以下要求:
- 通過密碼進(jìn)行客戶端身份驗(yàn)證
- 通過公鑰進(jìn)行客戶端身份驗(yàn)證
- 服務(wù)器認(rèn)證
- 通過SFTP從本地主機(jī)上傳文件
- 通過SFTP將文件下載到本地主機(jī)
- 遠(yuǎn)程主機(jī)上的文件操作,例如通過SFTP移動(dòng),刪除,列出給定文件夾的所有子文件夾(在文件或文件夾等類型之后進(jìn)行過濾)
- 執(zhí)行普通的shell命令
讓我們更深入地了解這三個(gè)庫如何滿足需求。
客戶端認(rèn)證
這三個(gè)庫都支持兩種必需的身份驗(yàn)證方法。 SSHJ具有最清晰的身份驗(yàn)證API( SSHClient.authUserPass(),SSHClient.authUserPublicKey() )。
SSHClient sshClient= new SSHClient(); sshClient.connect(host);// only for public key authentication sshClient.authPublickey("user", "location to private key file");// only for password authentication sshClient.authPassword("user", "password");在Commons VFS中,身份驗(yàn)證配置取決于應(yīng)使用哪種身份驗(yàn)證。 對(duì)于公共密鑰身份驗(yàn)證,必須在FileSystemOption中設(shè)置私有密鑰,并且用戶名是連接URL的一部分。 對(duì)于密碼驗(yàn)證,用戶名和密碼是連接URL的一部分。
StandardFileSystemManager fileSystemManager = new StandardFileSystemManager(); fileSystemManager.init();// only for public key authentication SftpFileSystemConfigBuilder sftpConfigBuilder = SftpFileSystemConfigBuilder.getInstance(); FileSystemOptions opts = new FileSystemOptions(); sftpConfigBuilder.setIdentities(opts, new File[]{privateKey.toFile()}); String connectionUrl = String.format("sftp://%s@%s", user, host);// only for password authentication String connectionUrl = String.format("sftp://%s:%s@%s", user, password, host);// Connection set-up FileObject remoteRootDirectory = fileSystemManager.resolveFile(connectionUrl, connectionOptions);JSch中的認(rèn)證配置類似于Commons VFS。 這取決于應(yīng)使用哪種身份驗(yàn)證。 必須在JSch對(duì)象中配置用于公共密鑰認(rèn)證的私鑰,并且必須在Session對(duì)象中設(shè)置用于密碼認(rèn)證的密碼。 對(duì)于兩者,當(dāng)JSch對(duì)象獲取Session對(duì)象時(shí),將設(shè)置用戶名。
JSch sshClient = new JSch();// only for public key authentication sshClient.addIdentity("location to private key file");session = sshClient.getSession(user, host);// only for password authentication session.setPassword(password);session.connect();服務(wù)器認(rèn)證
這三個(gè)庫均支持服務(wù)器身份驗(yàn)證。 在SSHJ中,可以使用SSHClient.loadKnownHost啟用服務(wù)器身份驗(yàn)證。 可以添加自己的known_host文件位置,也可以使用默認(rèn)位置,該位置取決于使用平臺(tái)。
SSHClient sshClient = new SSHClient(); sshClient.loadKnownHosts(); // or sshClient.loadKnownHosts(knownHosts.toFile()); sshClient.connect(host);在Commons VFS中,服務(wù)器身份驗(yàn)證配置也是FileSystemOption的一部分,類似于公鑰身份驗(yàn)證。 在那里,可以設(shè)置known_hosts文件的位置。
SftpFileSystemConfigBuilder sftpConfigBuilder = SftpFileSystemConfigBuilder.getInstance(); FileSystemOptions opts = new FileSystemOptions(); sftpConfigBuilder.setKnownHosts(opts, new File("location of the known_hosts file"));在JSch中,存在兩種配置服務(wù)器身份驗(yàn)證的可能性。 一種可能性是使用OpenSSHConfig (請(qǐng)參閱JSch示例以了解OpenSSHConfig )。 另一種可能性更容易。 可以直接在JSch對(duì)象中設(shè)置known_hosts文件的位置。
JSch sshClient = new JSch(); sshClient.setKnownHosts("location of known-hosts file");通過SFTP上傳/下載文件
這三個(gè)庫均支持通過SFTP上傳和下載文件。 SSHJ具有非常清晰的API用于這些操作。 SSHClient對(duì)象創(chuàng)建一個(gè)SFTPClient對(duì)象。 這個(gè)對(duì)象負(fù)責(zé)上傳(SFTPClient。PUT)和下載(SFTPClient。 獲得 )。
SSHClient sshClient = new SSHClient(); // ... connectiontry (SFTPClient sftpClient = sshClient.newSFTPClient()) {// downloadsftpClient.get(remotePath, new FileSystemFile(local.toFile()));// uploadsftpClient.put(new FileSystemFile(local.toFile()), remotePath); }在Commons VFS中,上傳和下載文件被抽象為在文件系統(tǒng)上的操作。 因此,兩者均由FileObject對(duì)象的copyFrom方法表示。 上傳是參數(shù)】remotefile對(duì)象上的copyfrom操作和下載是在LOCALFILE一個(gè)的copyfrom操作。
StandardFileSystemManager?fileSystemManager = new StandardFileSystemManager(); // ... configuration remoteRootDirectory = fileSystemManager.resolveFile(connectionUrl, connectionOptions);LocalFile localFileObject = (LocalFile) fileSystemManager.resolveFile(local.toUri().toString()); FileObject remoteFileObject = remoteRootDirectory.resolveFile(remotePath); try {// downloadlocalFileObject.copyFrom(remoteFileObject, new AllFileSelector());// uploadremoteFileObject.copyFrom(localFileObject, new AllFileSelector()); } finally {localFileObject.close();remoteFileObject.close(); }JSch還支持SFTPClient。 在JSch中,它稱為ChannelSFTP 。 它有兩種下載( ChannelSFTP.get )和上載( ChannelSFTP.put )的方法。
// here: creation and configuration of sessionChannelSftp sftpChannel = null; try {sftpChannel = (ChannelSftp) session.openChannel("sftp");sftpChannel.connect();// downloadInputStream inputStream = sftpChannel.get(remotePath);Files.copy(inputStream, localPath);// uploadOutputStream outputStream = sftpChannel.put(remotePath);Files.copy(locaPathl, outputStream); } catch (SftpException | JSchException ex) {throw new IOException(ex); } finally {if (sftpChannel != null) {sftpChannel.disconnect();} }執(zhí)行Shell命令
僅Commons VFS不支持執(zhí)行普通Shell命令。 在SSHJ中,它是兩層的。 SshClient啟動(dòng)一個(gè)新的Session對(duì)象。 該對(duì)象執(zhí)行shell命令。 這是非常直觀的。
// creation and configuration of sshClienttry (Session session = sshClient.startSession()) {session.exec("ls"); }在Jsch中, ChannelExec負(fù)責(zé)通過SSH執(zhí)行Shell命令。 首先,在通道中設(shè)置命令,然后必須啟動(dòng)通道。 它不像SSHJ那樣直觀。
// here: creation and configuration of session objectChannelExec execChannel = null; try {execChannel = (ChannelExec) session.openChannel("exec");execChannel.connect();execChannel.setCommand(command);execChannel.start(); } catch (JSchException ex) {throw new IOException(ex); } finally {if (execChannel != null) {execChannel.disconnect();} }遠(yuǎn)程主機(jī)上的文件操作
所有庫都通過遠(yuǎn)程計(jì)算機(jī)上的SFTP支持或多或少的理想文件操作。 在SSHJ中, SFTPClient也具有用于文件操作的方法。 方法的名稱與Linux系統(tǒng)上的文件操作相同。 以下代碼段顯示了如何刪除文件。
//here: creation and configuration of sshClienttry (SFTPClient sftpClient = sshClient.newSFTPClient()) {sftpClient.rm(remotePath); }Commons VFS的核心功能是文件操作。 用法需要習(xí)慣。 必須解析文件對(duì)象,并且可以對(duì)其執(zhí)行文件操作。
// here: creation and configuration of remoteRootDirectoryFileObject remoteFileObject = remoteRootDirectory.resolveFile(remotePath); try {remoteFileObject.delete(); } finally {remoteFileObject.close(); }JSch的SFTPClient ChannelSFTP也具有文件操作方法。 此通道支持大多數(shù)文件操作。 例如,必須通過ChannelExec上的簡單外殼命令來完成遠(yuǎn)程計(jì)算機(jī)上的文件復(fù)制操作。
// here: creation and configuration of session ChannelSftp sftpChannel = null; try {sftpChannel = (ChannelSftp) session.openChannel("sftp");sftpChannel.connect();sftpChannel.rm(remotePath); } catch (SftpException | JSchException ex) {throw new IOException(ex); } finally {if (sftpChannel != null) {sftpChannel.disconnect();} }結(jié)論
比較之后,我有兩個(gè)收藏夾,SSHJ和Commons VFS。 SSHJ具有非常清晰的API,如果我需要通用的SSH客戶端或通過SFTP進(jìn)行文件操作就足夠了,我會(huì)選擇它。 如果我可以通過許多文件系統(tǒng)協(xié)議進(jìn)行文件操作,或者不需要通用的SSH客戶端,則可以選擇Commons VFS。 對(duì)于這兩種情況,我可以同時(shí)使用JSch來通過SSH執(zhí)行命令。 Commons VFS的API已經(jīng)習(xí)慣了。 但是在了解了背后的概念之后,API的用法就很簡單了。
這個(gè)比較的整個(gè)源代碼示例都托管在Github上 。
有用的鏈接
翻譯自: https://www.javacodegeeks.com/2015/08/commons-vfs-sshj-and-jsch-in-comparison.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的比较中的Commons VFS,SSHJ和JSch的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 光猫连接无线路由器用路由器拨号怎么设置移
- 下一篇: 怎样选一个好车牌如何在电脑上选车牌号