惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
月光博客
月光博客
博客园_首页
博客园 - 叶小钗
T
Tailwind CSS Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
I
InfoQ
量子位
小众软件
小众软件
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
IT之家
IT之家
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

风萧古道 - 勤学苦练,年复一年

AI 编程时代,想象力成了最被奖励的能力 游戏服务器开发经验(五)应对复杂需求 沉浸式体验东汉末年生活 - 《真三国无双 起源》玩后感 怒其不争!致2025年HLTV的Top18-NiKo Linux家用服务器维护指南 游戏服务器开发经验(四)避免写Bug的习惯、技巧和心态 游戏服务器开发经验(三)线上维护 游戏服务器开发经验(二)避免内存泄露 游戏服务器开发经验(一)道具防刷 35岁找不到工作,绝对不会是软件开发人员的结局 用爱发电项目开发两个月的心得体会 以魏延“子午谷奇谋”讨论软件需求可行性问题 MQTT协议中可变长度的具体计算方式(有计算过程解析) 关于游戏服务器配置表功能的探讨 Java并发编程中上锁的几种方式 如何用C++分割一个字符串? CSAPP第二章-信息的表示与处理 我的自我介绍 Windows XP虚拟机中文版无需激活下载 Java TreeSet的一些用法和特性 Linux C++ Socket实战 传统软件服务器与游戏服务器架构区别 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废 使用Python实现简单UDP Ping 使用Python开发一个简单的web服务器 Kotlin手动实现一个最简单的哈希表 Kotlin实现二叉堆、大顶堆、优先级队列 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建 Springboot操作MongoDB,包括增改查及复杂操作 Unison在Linux下的安装与使用
Java实现类似WINSCP访问远程Linux服务器,执行命令、上传文件...
JonathanLin · 2020-02-20 · via 风萧古道 - 勤学苦练,年复一年

pom.xml添加的依赖:

<!-- https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2 --> 
<dependency> 
    <groupId>ch.ethz.ganymed</groupId> 
    <artifactId>ganymed-ssh2</artifactId> 
    <version>262</version> 
</dependency>

这里注意,不同版本的这玩意用法有差别。这里我使用的是262。

操作类代码如下:

import ch.ethz.ssh2.*;

import java.io.*;

/**
 * @Author: 风萧古道的博客 windypath.com
 * @Date: 2019/11/29 15:14
 */
public class SSHUtil {

    // uploadFile to Linux

    /**
     * 上传文件到Linux
     * 
     * @param ip ip地址
     * @param username 登录用户名
     * @param password 密码
     * @param remoteFilePath 目标文件所在完整目录
     * @param file 本地文件File对象
     * @return
     */
    public static boolean uploadFile(String ip, String username, String password, String remoteFilePath, File file) {

        FileInputStream input = null;
        BufferedOutputStream boutput = null;
        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            boutput = scpClient.put(file.getName(), file.length(), remoteFilePath, "0600");
            byte[] buffer = new byte[1024 * 8];
            input = new FileInputStream(file);


            int length = -1;
            while ((length = input.read(buffer)) != -1) {
                boutput.write(buffer, 0, length);
            }
            boutput.flush();

        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {
            try {

                boutput.close();
                input.close();
                conn.close();
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }
        return true;
    }


  
    /**
     * 从远程服务器上下载文件
     *
     * @param ip ip地址
     * @param username 用户名
     * @param password 密码
     * @param remoteFile 要下载的文件的完整路径
     * @param localFileName 下载到本地的文件名
     * @return
     */
    public static boolean downloadFile(String ip, String username, String password, String remoteFile, String localFileName) {
        SCPInputStream binput = null;
        FileOutputStream output = null;
        BufferedOutputStream boutput = null;
        Connection conn = null;
        try {
            File file = new File(localFileName);
            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            binput = scpClient.get(remoteFile);
            output = new FileOutputStream(file);
            boutput = new BufferedOutputStream(output);
            byte[] buffer = new byte[1024 * 8];
            int length = -1;
            while ((length = binput.read(buffer)) != -1) {
                boutput.write(buffer, 0, length);
            }


        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                binput.close();
                boutput.close();
                output.close();
                conn.close();
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }
        return true;
    }

    /**
     * 获取远程文件的输入流
     *
     * @param ip ip
     * @param username 用户名
     * @param password 密码
     * @param remoteFile 远程文件的完整地址
     * @return 输入流
     */
    public static SCPInputStream getRemoteFileInputStream(String ip, String username, String password, String remoteFile) {
        SCPInputStream binput = null;

        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            SCPClient scpClient = conn.createSCPClient();
            binput = scpClient.get(remoteFile);

        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return binput;
    }

    /**
     * 执行远程服务器的控制台命令
     *
     * @param ip ip地址
     * @param username 用户名
     * @param password 密码
     * @param cmd 控制台命令
     */
    public static void executeCmd(String ip, String username, String password, String cmd) {
        Connection conn = null;
        try {

            conn = new Connection(ip);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username, password);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            Session sess = conn.openSession();
            sess.execCommand(cmd + "\n");
            InputStream stdout = new StreamGobbler(sess.getStdout());
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(stdout));
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);
            }


        } catch (IOException e) {
            e.printStackTrace(System.err);
        } finally {

            conn.close();

        }
    }

}

值得一提的是,uploadFile()方法的最后一个参数传入的是指向本地文件的一个File,也就是要上传的文件,而在downloadFile()方法中,最后一个参数是字符串,就是将目标文件下载下来之后,要叫什么名字,记得带上后缀。

执行命令的话,执行一次就新开一次session。一个session(好像貌似)不能做两件事(如上传文件的过程中创建一个新文件夹,再以新文件夹的目录为目标上传目录)。