JSch 是一个纯 java 的 ssh2 实现。主要用来连接 ssh 和 sftp。
官网在此: http://www.jcraft.com/jsch/
<dependency>
<groupId>com.jcraftgroupId>
<artifactId>jschartifactId>
<version>0.1.55version>
dependency>
JSCHUtil 类主要有以下方法:
# vim d:/temp/JSCHUtil.java
import com.jcraft.jsch.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class JSCHUtil {
private static JSch jsch = new JSch();
public static void main(String[] args) throws JSchException {
Session session = JSCHUtil.createSession("10.161.97.205", 22, "root", "");
JSCHUtil.remoteExecute(session, "df -Th");
long l1 = JSCHUtil.scpTo(session, "d:/temp/README.md", "/root/README.md");
System.out.println(l1);
long l2 = JSCHUtil.scpFrom(session, "/root/README.md", "d:/temp/README.txt");
System.out.println(l2);
List<String> strings = JSCHUtil.listFilesOnSFTP(session, "/root");
for (String name: strings) {
System.out.println("/" + name);
}
boolean b1 = JSCHUtil.uploadToSFTP(session, "d:/temp/README.md", "/root/README.SFTP");
System.out.println(b1);
boolean b2 = JSCHUtil.downloadFromSFTP(session, "/root/README.SFTP", "d:/temp/README.SFTP");
System.out.println(b2);
session.disconnect();
}
public static Session createSession(String ip, int port, String user, String password) throws JSchException {
JSch jSch = new JSch();
Session session = jSch.getSession(user, ip, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
return session;
}
public static List<String> remoteExecute(Session session, String command) throws JSchException {
List<String> resultLines = new ArrayList<>();
ChannelExec channel = null;
try {
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
InputStream input = channel.getInputStream();
channel.connect();
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(input));
String inputLine = null;
while ((inputLine = inputReader.readLine()) != null) {
System.out.println(inputLine);
resultLines.add(inputLine);
}
} finally {
if (input != null) {
try {
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (channel != null) {
try {
channel.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return resultLines;
}
public static long scpTo(Session session, String source, String destination) {
FileInputStream fileInputStream = null;
try {
ChannelExec channel = (ChannelExec) session.openChannel("exec");
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
boolean ptimestamp = false;
String command = "scp";
if (ptimestamp) {
command += " -p";
}
command += " -t " + destination;
channel.setCommand(command);
channel.connect();
if (checkAck(in) != 0) {
return -1;
}
File _lfile = new File(source);
if (ptimestamp) {
command = "T " + (_lfile.lastModified() / 1000) + " 0";
// The access time should be sent here,
// but it is not accessible with JavaAPI ;-<
command += (" " + (_lfile.lastModified() / 1000) + " 0\n");
out.write(command.getBytes());
out.flush();
if (checkAck(in) != 0) {
return -1;
}
}
//send "C0644 filesize filename", where filename should not include '/'
long fileSize = _lfile.length();
command = "C0644 " + fileSize + " ";
if (source.lastIndexOf('/') > 0) {
command += source.substring(source.lastIndexOf('/') + 1);
} else {
command += source;
}
command += "\n";
out.write(command.getBytes());
out.flush();
if (checkAck(in) != 0) {
return -1;
}
//send content of file
fileInputStream = new FileInputStream(source);
byte[] buf = new byte[1024];
long sum = 0;
while (true) {
int len = fileInputStream.read(buf, 0, buf.length);
if (len <= 0) {
break;
}
out.write(buf, 0, len);
sum += len;
}
//send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
if (checkAck(in) != 0) {
return -1;
}
return sum;
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return -1;
}
public static long scpFrom(Session session, String source, String destination) {
FileOutputStream fileOutputStream = null;
try {
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("scp -f " + source);
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
byte[] buf = new byte[1024];
//send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
while (true) {
if (checkAck(in) != 'C') {
break;
}
}
//read '644 '
in.read(buf, 0, 4);
long fileSize = 0;
while (true) {
if (in.read(buf, 0, 1) < 0) {
break;
}
if (buf[0] == ' ') {
break;
}
fileSize = fileSize * 10L + (long) (buf[0] - '0');
}
String file = null;
for (int i = 0; ; i++) {
in.read(buf, i, 1);
if (buf[i] == (byte) 0x0a) {
file = new String(buf, 0, i);
break;
}
}
// send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
// read a content of lfile
if (Files.isDirectory(Paths.get(destination))) {
fileOutputStream = new FileOutputStream(destination + File.separator + file);
} else {
fileOutputStream = new FileOutputStream(destination);
}
long sum = 0;
while (true) {
int len = in.read(buf, 0, buf.length);
if (len <= 0) {
break;
}
sum += len;
if (len >= fileSize) {
fileOutputStream.write(buf, 0, (int) fileSize);
break;
}
fileOutputStream.write(buf, 0, len);
fileSize -= len;
}
return sum;
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return -1;
}
private static int checkAck(InputStream in) throws IOException {
int b = in.read();
// b may be 0 for success,
// 1 for error,
// 2 for fatal error,
// -1
if (b == 0) return b;
if (b == -1) return b;
if (b == 1 || b == 2) {
StringBuffer sb = new StringBuffer();
int c;
do {
c = in.read();
sb.append((char) c);
}
while (c != '\n');
if (b == 1) { // error
System.out.println(sb.toString());
}
if (b == 2) { // fatal error
System.out.println(sb.toString());
}
}
return b;
}
public static List<String> listFilesInSFTP(Session session, String path) {
ArrayList<String> fileList = new ArrayList<String>();
try {
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
channel.connect();
Vector vv = channel.ls(path);
if (vv != null) {
for (int ii = 0; ii < vv.size(); ii++) {
Object obj = vv.elementAt(ii);
if (obj instanceof com.jcraft.jsch.ChannelSftp.LsEntry) {
fileList.add(((com.jcraft.jsch.ChannelSftp.LsEntry) obj).getFilename());
}
}
}
} catch (SftpException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
}
return fileList;
}
public static boolean uploadToSFTP(Session session, String source, String destination) {
try {
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
channel.connect();
try {
channel.put(source, destination);
return true;
} catch (SftpException e) {
e.printStackTrace();
}
} catch (JSchException e) {
e.printStackTrace();
}
return false;
}
public static boolean downloadFromSFTP(Session session, String source, String destination) {
try {
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
channel.connect();
try {
channel.get(source, destination);
return true;
} catch (SftpException e) {
e.printStackTrace();
}
} catch (JSchException e) {
e.printStackTrace();
}
return false;
}
}
# 将 jsch-0.1.55.jar 解压至 D:\temp, 注意,com 目录与 JSCHUtil.java 文件在同一父目录下。
# 编译
D:\temp>javac -cp . JSCHUtil.java
# 运行
D:\temp>java JSCHUtil
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-lv_root xfs 50G 22G 28G 45% /
/dev/xvde1 xfs 500G 158G 343G 32%
/dev/xvda1 xfs 1014M 207M 808M 21% /boot
/dev/mapper/centos-home xfs 42G 386M 41G 1%
5804
5805
/.ssh
/.bash_profile
/README.md
/README.SFTP
true
true