OutputStreamWriter 本身不直接连接 SSH,需通过 JSCH 等库获取 SSH channel 的输出流后包装使用;必须指定编码(如 UTF-8)、添加目标系统换行符(如 \n)、调用 flush(),并确保远端 locale 编码匹配。

OutputStreamWriter 本身不直接连接 SSH,它只是 Java I/O 中用于将字符流编码写入字节流的桥接类。要向 SSH 远程终端发送特定编码的命令,关键在于:先建立 SSH 连接并获取其输入流(即远程 shell 的 stdin),再用 OutputStreamWriter 包装该流,并指定所需字符编码。
1. 使用 JSCH 等 SSH 库获取远程 stdin 流
Java 标准库不提供 SSH 支持,需依赖第三方库(如 JSCH)。通过 JSCH 建立会话、打开 channel(如 ChannelShell),再调用 getOutputStream() 获取可写入的字节流 —— 这就是远程终端的标准输入。
- 确保 channel 已 connect(),且已调用 setPty(true)(启用伪终端)以支持交互式命令和正确处理换行、编码等
- 不要直接对 socket 或底层流操作;必须走 SSH 协议封装的 channel 输出流
2. 用 OutputStreamWriter 指定编码包装输出流
拿到 channel 的 getOutputStream() 后,将其传给 OutputStreamWriter 构造器,并显式传入编码名(如 "UTF-8" 或 "GBK")。这确保你写的字符串按指定编码转为字节后,经 SSH 加密传输到远端。
- 示例:
new OutputStreamWriter(channel.getOutputStream(), "UTF-8") - 远端系统需能识别该编码(如 Linux 终端通常默认 UTF-8;Windows Server 可能需 GBK 或 CP1252)
- 避免用
new OutputStreamWriter(out)无参构造 —— 它依赖平台默认编码,不可控
3. 发送命令时注意换行与刷新
SSH 终端靠换行符触发命令执行,所以每条命令末尾必须加 \n(Unix 风格)或 \r\n(部分 Windows 终端)。写完后调用 flush(),否则内容可能滞留在缓冲区不发出。
立即学习“Java免费学习笔记(深入)”;
writer.write("ls -la\n"); writer.flush();- 若连续写多条,建议每次写完都 flush;或使用
new OutputStreamWriter(..., true)启用自动 flush(仅对 write(int) 和 write(String) 生效) - 不要用 println() —— 它添加的是平台相关换行符,而 SSH 远端期望的是目标系统约定的换行
4. 编码一致性需两端协同
即使 Java 端用 UTF-8 写出,若远端 shell 环境(如 LANG=en_US.ISO-8859-1)不匹配,仍可能显示乱码或报错。务必确认远端终端编码设置:
- 登录后执行
locale查看当前编码 - 可通过
writer.write("export LANG=en_US.UTF-8\n")提前设置(需在命令前发送) - 中文环境常见组合:Java 端用 "UTF-8",远端设 LANG=zh_CN.UTF-8


















