SSH
ドキュメントをダウンロード
1. まず、Linux サーバー上でダウンロードするファイルを見つけます。
ここでは、Ghost Knife.png というファイル名で画像をダウンロードしたいと思います。ファイル パスは /home/myqxin/Ghost Knife.png です。
2. Windows 上のファイルの保存場所 (カスタマイズ)
3. 次のテストコードを実行します。
package com.czxy.music.web.test.day02;
import ch.ethz.ssh2.Connection;
import com.czxy.music.utils.RemoteCommandUtil;
/**
* Created by zfwy on 2020/9/25.
*/
public class Myqxin {
public static void main(String[] args)throws Exception {
// 创建服务对象
RemoteCommandUtil commandUtil = new RemoteCommandUtil();
// 登录到LInux服务
Connection root = commandUtil.login("服务器ip", "用户名", "密码");
// 服务器文件路径
String fwPath = "/home/myqxin";
// windows本地存放目录,不需要加上具体文件
String bdPath = "D:\\Music\\";
// 下载文件
commandUtil.downloadFile(root,"鬼刀.png",fwPath,bdPath,null);
// 批量下载
// commandUtil.downloadDirFile(root,fwPath,bdPath);
}
}
サーバー IP: LInux がアクセスする IP アドレスです (例: (172.18.0.2) と入力します。
サービス ユーザー名: Linux ユーザー名、通常は (root) ユーザーです。
サービス パスワード: のパスワードです。 Linux ユーザーです。賢い人なら忘れないでしょう。
実行の効果は次のとおりです。
4. ストリーミング経由でダウンロードする この方法では、プロジェクトの展開を考慮する必要がありません。
@GetMapping("/downimage")
public void downimage(HttpServletResponse response) throws Exception {
// 创建服务对象
RemoteCommandUtil commandUtil = new RemoteCommandUtil();
// 登录到LInux服务
Connection root = commandUtil.login("192.168.124.156", "root", "root");
// 服务器文件路径
String fwPath = "/home/data/images";
commandUtil.downloadFileFlow(root,"sun.jpeg",fwPath,response);
}
ファイルのアップロード
1. サーバーにアップロードするアドレスをカスタマイズします
2. アップロードしたいファイルを見つけます
Ghost Knife.png 画像をサーバーからダウンロードしました。次に、sun.jpeg ファイルをサーバーにアップロードしたいと思います。
3. 次のテストコードを実行します。
public class Myqxin {
public static void main(String[] args)throws Exception {
// 创建服务对象
RemoteCommandUtil commandUtil = new RemoteCommandUtil();
// 登录到LInux服务
Connection root = commandUtil.login("服务器ip", "用户名", "密码");
// 服务器文件路径
String fwPath = "/home/myqxin";
// 上传文件
File file = new File("D:\\Music\\sun.jpeg");
// 如果存在
// if(file.exists()){
// 文件重命名
// String newname = "新名称"+".jpeg";
// File newFile = new File(file.getParent() + File.separator + newname);
// if (file.renameTo(newFile))
// commandUtil.uploadFile(root,newFile,fwPath,null);
// }
commandUtil.uploadFile(root,file,fwPath,null);
}
}
実行効果は以下の通りです。
以下はRemoteCommandUtil.javaのソースコードです。
package com.myqxin.common.utils;
import ch.ethz.ssh2.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author zfwy
*/
@Slf4j
public class RemoteCommandUtil {
//目标服务器端口,默认
private static int port = 22;
private static Connection conn = null;
/**
* 登录服务器主机
*
* @param ip 主机IP
* @param userName 用户名
* @param userPwd 密码
* @return 登录对象
*/
public static Connection login(String ip, String userName, String userPwd) {
boolean flg = false;
Connection conn = null;
try {
conn = new Connection(ip, port);
//连接
conn.connect();
//认证
flg = conn.authenticateWithPassword(userName, userPwd);
if (flg) {
log.info("连接成功");
return conn;
}
} catch (IOException e) {
log.error("连接失败" + e.getMessage());
e.printStackTrace();
}
return conn;
}
/**
* 通过流下载到本地
*
* @param conn SSH连接信息
* @param fileName 要下载的具体文件名称
* @param basePath 服务器上的文件地址/home/img
* @throws IOException
*/
public void downloadFileFlow(Connection conn, String fileName, String basePath, HttpServletResponse response) throws IOException {
SCPClient scpClient = conn.createSCPClient();
try {
SCPInputStream sis = scpClient.get(basePath + "/" + fileName);
SCPInputStream two = scpClient.get(basePath + "/" + fileName);;
long file_length = getFileSizeByByteArrayOutputStream(two);
// 以流的形式下载文件。
byte[] buffer = new byte[(int) file_length];
sis.read(buffer);
sis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
response.addHeader("Content-Length", "" + file_length);
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException e) {
log.info("文件不存在或连接失败");
e.printStackTrace();
} finally {
log.info("服务关闭");
closeConn();
}
}
public static long getFileSizeByByteArrayOutputStream(InputStream inputStream) {
ByteArrayOutputStream bos = null;
try {
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
return bos.size();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return -1;
}
/**
* 实现下载服务器上的文件到本地指定目录
*
* @param conn SSH连接信息
* @param fileName 要下载的具体文件名称
* @param basePath 服务器上的文件地址/home/img
* @param localPath 本地路径:D:\
* @param newName 文件重命名
* @throws IOException
*/
public void downloadFile(Connection conn, String fileName, String basePath, String localPath, String newName) throws IOException {
SCPClient scpClient = conn.createSCPClient();
try {
SCPInputStream sis = scpClient.get(basePath + "/" + fileName);
File f = new File(localPath);
if (!f.exists()) {
f.mkdirs();
}
File newFile = null;
if (StringUtils.isBlank(newName)) {
newFile = new File(localPath + fileName);
} else {
newFile = new File(localPath + newName);
}
FileOutputStream fos = new FileOutputStream(newFile);
byte[] b = new byte[4096];
int i;
while ((i = sis.read(b)) != -1) {
fos.write(b, 0, i);
}
fos.flush();
fos.close();
sis.close();
log.info("下载完成");
} catch (IOException e) {
log.info("文件不存在或连接失败");
e.printStackTrace();
} finally {
log.info("服务关闭");
closeConn();
}
}
/**
* 上传文件到服务器
*
* @param conn SSH连接信息
* @param f 文件对象
* @param remoteTargetDirectory 上传路径
* @param mode 默认为null
*/
public void uploadFile(Connection conn, File f, String remoteTargetDirectory, String mode) {
try {
SCPClient scpClient = new SCPClient(conn);
SCPOutputStream os = scpClient.put(f.getName(), f.length(), remoteTargetDirectory, mode);
byte[] b = new byte[4096];
FileInputStream fis = new FileInputStream(f);
int i;
while ((i = fis.read(b)) != -1) {
os.write(b, 0, i);
}
os.flush();
fis.close();
os.close();
log.info("上传成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
closeConn();
}
}
/**
* 关闭服务
*/
public static void closeConn() {
if (null == conn) {
return;
}
conn.close();
}
/**
* 批量下载目录所有文件
*
* @param root SSH连接信息
* @param fwPath 服务器上的文件地址/home/img
* @param bdPath 本地路径:D:\
*/
public void downloadDirFile(Connection root, String fwPath, String bdPath) throws IOException {
SCPClient scpClient = root.createSCPClient();
try {
List<String> allFilePath = getAllFilePath(root, fwPath);
File f = new File(bdPath);
if (!f.exists()) {
f.mkdirs();
}
FileOutputStream fos = null;
SCPInputStream sis = null;
for (String path : allFilePath) {
String[] split = path.split("/");
String filename = split[split.length - 1];
sis = scpClient.get(path);
File newFile = new File(bdPath);
fos = new FileOutputStream(newFile + "\\" + filename);
byte[] b = new byte[4096];
int i;
while ((i = sis.read(b)) != -1) {
fos.write(b, 0, i);
}
}
fos.flush();
fos.close();
sis.close();
log.info("下载完成");
} catch (IOException e) {
log.info("文件不存在或连接失败");
e.printStackTrace();
} finally {
log.info("服务关闭");
closeConn();
}
}
/**
* 获取目录下所有文件路径
*
* @param conn
* @param fwPath
* @return
*/
public List<String> getAllFilePath(Connection conn, String fwPath) {
List<String> folderNameList = new ArrayList<String>();
try {
// 创建一个会话
Session sess = conn.openSession();
sess.requestPTY("bash");
sess.startShell();
StreamGobbler stdout = new StreamGobbler(sess.getStdout());
StreamGobbler stderr = new StreamGobbler(sess.getStderr());
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stdout));
PrintWriter out = new PrintWriter(sess.getStdin());
out.println("cd " + fwPath);
out.println("ll");
out.println("exit");
out.close();
sess.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, 30000);
while (true) {
String line = stdoutReader.readLine();
if (line == null)
break;
//获取文件名称
if (line.contains("-rw-r--r--")) {
//取出正确的文件名称
StringBuffer sb =
new StringBuffer(line.substring(line.lastIndexOf(":") + 3, line.length()));
line = sb.toString().replace(" ", fwPath + "/");
folderNameList.add(line);
}
}
//关闭连接
sess.close();
stderrReader.close();
stdoutReader.close();
} catch (IOException e) {
log.info("文件不存在或连接失败");
System.exit(2);
e.printStackTrace();
} finally {
log.info("服务关闭");
closeConn();
}
return folderNameList;
}
}
SSH 依存関係を pom.xml にインポートする必要があります
<!-- SSH2 -->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>