做种/文件转发
parent
e1fc19aeab
commit
c96a251bde
|
@ -0,0 +1,14 @@
|
|||
package com.unisinsight.project.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
WebMvcConfigurer.super.addResourceHandlers(registry);
|
||||
registry.addResourceHandler("/api/vdi/file/down/**").addResourceLocations("file:/var/lib/vdi/test/");
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.unisinsight.project.controller;
|
||||
|
||||
import com.unisinsight.project.util.BtTorrentUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
@ -9,94 +10,11 @@ import java.io.*;
|
|||
@Slf4j
|
||||
public class TestController {
|
||||
|
||||
|
||||
private static final String BT_SCRIPT_PATH = "/var/lib/vdi/nodejs/bttorrent.sh";
|
||||
private static final String RUN_USER = "java_usr"; // 替换为你的实际用户
|
||||
|
||||
/**
|
||||
* 制作种子并开始做种
|
||||
*
|
||||
* @param sourceFile 源文件路径(如 /data/file.iso)
|
||||
* @param torrentFile 生成的种子文件路径(如 /data/file.torrent)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean createAndSeed(String sourceFile, String torrentFile) {
|
||||
// 验证文件是否存在
|
||||
if (!new File(sourceFile).exists()) {
|
||||
System.err.println("源文件不存在: " + sourceFile);
|
||||
return false;
|
||||
}
|
||||
// 确保目标目录存在
|
||||
new File(torrentFile).getParentFile().mkdirs();
|
||||
return executeCommand("start", sourceFile, torrentFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止指定文件的做种
|
||||
*
|
||||
* @param sourceFile 源文件路径(如 /data/file.iso)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean stopSeeding(String sourceFile) {
|
||||
return executeCommand("stop_path", sourceFile, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 bttorrent.sh 脚本
|
||||
*/
|
||||
private static boolean executeCommand(String command, String arg1, String arg2) {
|
||||
try {
|
||||
// 构造命令
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"sudo", "-u", RUN_USER,
|
||||
BT_SCRIPT_PATH,
|
||||
command,
|
||||
arg1,
|
||||
arg2 != null ? arg2 : "" // 处理可选参数
|
||||
).redirectErrorStream(true);
|
||||
// 启动进程
|
||||
Process process = pb.start();
|
||||
// 打印输出(调试用)
|
||||
logProcessOutput(process);
|
||||
// 等待执行完成
|
||||
return process.waitFor() == 0;
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印进程输出
|
||||
*/
|
||||
private static void logProcessOutput(Process process) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println("[BT] " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 测试用例
|
||||
public static void main(String[] args) {
|
||||
String sourceFile = "/var/lib/vdi/test/example.iso";
|
||||
String torrentFile = "/var/lib/vdi/test/example.torrent";
|
||||
// 测试做种
|
||||
System.out.println("开始做种...");
|
||||
boolean seedResult = createAndSeed(sourceFile, torrentFile);
|
||||
System.out.println("做种结果: " + (seedResult ? "成功" : "失败"));
|
||||
// 测试停止
|
||||
System.out.println("停止做种...");
|
||||
boolean stopResult = stopSeeding(sourceFile);
|
||||
System.out.println("停止结果: " + (stopResult ? "成功" : "失败"));
|
||||
}
|
||||
|
||||
@GetMapping("/start")
|
||||
public String start(@RequestParam("sourceFile") String sourceFile,
|
||||
@RequestParam("torrentFile") String torrentFile) {
|
||||
System.out.println("开始做种...");
|
||||
boolean seedResult = createAndSeed(sourceFile, torrentFile);
|
||||
boolean seedResult = BtTorrentUtils.createAndSeed(sourceFile, torrentFile);
|
||||
System.out.println("做种结果: " + (seedResult ? "成功" : "失败"));
|
||||
return "success";
|
||||
}
|
||||
|
@ -105,7 +23,7 @@ public class TestController {
|
|||
public String stop(@RequestParam("sourceFile") String sourceFile) {
|
||||
// 测试停止
|
||||
System.out.println("停止做种...");
|
||||
boolean stopResult = stopSeeding(sourceFile);
|
||||
boolean stopResult = BtTorrentUtils.stopSeeding(sourceFile);
|
||||
System.out.println("停止结果: " + (stopResult ? "成功" : "失败"));
|
||||
return "success";
|
||||
}
|
||||
|
|
|
@ -1,429 +0,0 @@
|
|||
package com.unisinsight.project.util;
|
||||
|
||||
import com.dampcake.bencode.BencodeInputStream;
|
||||
import com.dampcake.bencode.BencodeOutputStream;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BT种子生成和下载工具类
|
||||
*/
|
||||
public class BtTorrentUtil {
|
||||
|
||||
/**
|
||||
* 创建BT种子文件
|
||||
*
|
||||
* @param filePath 要分享的文件或目录路径
|
||||
* @param trackerUrl Tracker服务器地址
|
||||
* @param outputFile 生成的种子文件路径
|
||||
* @throws IOException IO异常
|
||||
* @throws URISyntaxException URI语法异常
|
||||
*/
|
||||
public static void createTorrent(String filePath, String trackerUrl, String outputFile)
|
||||
throws IOException, URISyntaxException {
|
||||
|
||||
Path path = Paths.get(filePath);
|
||||
if (!Files.exists(path)) {
|
||||
throw new FileNotFoundException("文件或目录不存在: " + filePath);
|
||||
}
|
||||
|
||||
// 验证tracker URL格式
|
||||
new URI(trackerUrl);
|
||||
|
||||
// 创建种子信息
|
||||
TorrentInfo torrentInfo = new TorrentInfo();
|
||||
torrentInfo.setAnnounce(trackerUrl);
|
||||
torrentInfo.setCreationDate(new Date().getTime() / 1000);
|
||||
torrentInfo.setCreatedBy("BtTorrentUtil v1.0");
|
||||
|
||||
// 处理文件信息
|
||||
if (Files.isDirectory(path)) {
|
||||
processDirectory(path, torrentInfo);
|
||||
} else {
|
||||
processFile(path, torrentInfo);
|
||||
}
|
||||
|
||||
// 生成种子文件
|
||||
writeTorrentFile(torrentInfo, outputFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个文件
|
||||
*/
|
||||
private static void processFile(Path filePath, TorrentInfo torrentInfo) throws IOException {
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.setLength(Files.size(filePath));
|
||||
fileInfo.setPath(new ArrayList<>());
|
||||
fileInfo.getPath().add(filePath.getFileName().toString());
|
||||
|
||||
List<FileInfo> files = new ArrayList<>();
|
||||
files.add(fileInfo);
|
||||
|
||||
torrentInfo.setFiles(files);
|
||||
torrentInfo.setName(filePath.getFileName().toString());
|
||||
torrentInfo.setPieceLength(524288); // 512KB
|
||||
|
||||
// 计算文件的pieces
|
||||
byte[] pieces = calculatePieces(filePath, torrentInfo.getPieceLength());
|
||||
torrentInfo.setPieces(pieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理目录
|
||||
*/
|
||||
private static void processDirectory(Path dirPath, TorrentInfo torrentInfo) throws IOException {
|
||||
List<FileInfo> files = new ArrayList<>();
|
||||
long totalSize = 0;
|
||||
|
||||
Files.walk(dirPath)
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach(file -> {
|
||||
try {
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.setLength(Files.size(file));
|
||||
List<String> pathList = new ArrayList<>();
|
||||
|
||||
// 获取相对路径
|
||||
Path relativePath = dirPath.relativize(file);
|
||||
for (Path part : relativePath) {
|
||||
pathList.add(part.toString());
|
||||
}
|
||||
|
||||
fileInfo.setPath(pathList);
|
||||
files.add(fileInfo);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
torrentInfo.setFiles(files);
|
||||
torrentInfo.setName(dirPath.getFileName().toString());
|
||||
torrentInfo.setPieceLength(524288); // 512KB
|
||||
|
||||
// 计算所有文件的pieces(简化实现)
|
||||
// 实际应用中需要按顺序读取所有文件数据来计算pieces
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (FileInfo file : files) {
|
||||
Path filePath = dirPath;
|
||||
for (String pathPart : file.getPath()) {
|
||||
filePath = filePath.resolve(pathPart);
|
||||
}
|
||||
if (Files.exists(filePath)) {
|
||||
Files.copy(filePath, baos);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] pieces = calculatePiecesFromData(baos.toByteArray(), torrentInfo.getPieceLength());
|
||||
torrentInfo.setPieces(pieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算文件的pieces哈希值
|
||||
*/
|
||||
private static byte[] calculatePieces(Path filePath, int pieceLength) throws IOException {
|
||||
ByteArrayOutputStream pieces = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[pieceLength];
|
||||
int bytesRead;
|
||||
|
||||
try (InputStream is = Files.newInputStream(filePath)) {
|
||||
while ((bytesRead = is.read(buffer)) != -1) {
|
||||
// 简化实现,实际应使用SHA1哈希
|
||||
// 这里只是示例,实际应用中需要计算SHA1
|
||||
byte[] hash = new byte[20]; // SHA1哈希长度为20字节
|
||||
for (int i = 0; i < Math.min(20, bytesRead); i++) {
|
||||
hash[i] = (byte) (buffer[i] % 256);
|
||||
}
|
||||
pieces.write(hash);
|
||||
}
|
||||
}
|
||||
|
||||
return pieces.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据计算pieces哈希值
|
||||
*/
|
||||
private static byte[] calculatePiecesFromData(byte[] data, int pieceLength) throws IOException {
|
||||
ByteArrayOutputStream pieces = new ByteArrayOutputStream();
|
||||
|
||||
for (int i = 0; i < data.length; i += pieceLength) {
|
||||
int length = Math.min(pieceLength, data.length - i);
|
||||
byte[] piece = new byte[length];
|
||||
System.arraycopy(data, i, piece, 0, length);
|
||||
|
||||
// 简化实现,实际应使用SHA1哈希
|
||||
byte[] hash = new byte[20];
|
||||
for (int j = 0; j < Math.min(20, length); j++) {
|
||||
hash[j] = (byte) (piece[j] % 256);
|
||||
}
|
||||
pieces.write(hash);
|
||||
}
|
||||
|
||||
return pieces.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入种子文件
|
||||
*/
|
||||
private static void writeTorrentFile(TorrentInfo torrentInfo, String outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
BencodeOutputStream bos = new BencodeOutputStream(fos)) {
|
||||
|
||||
// 构建种子数据结构
|
||||
java.util.Map<String, Object> torrentMap = new java.util.HashMap<>();
|
||||
torrentMap.put("announce", torrentInfo.getAnnounce());
|
||||
torrentMap.put("creation date", torrentInfo.getCreationDate());
|
||||
torrentMap.put("created by", torrentInfo.getCreatedBy());
|
||||
|
||||
// info字典
|
||||
java.util.Map<String, Object> infoMap = new java.util.HashMap<>();
|
||||
infoMap.put("name", torrentInfo.getName());
|
||||
infoMap.put("piece length", torrentInfo.getPieceLength());
|
||||
infoMap.put("pieces", torrentInfo.getPieces());
|
||||
|
||||
if (torrentInfo.getFiles() != null && !torrentInfo.getFiles().isEmpty()) {
|
||||
// 多文件模式
|
||||
List<java.util.Map<String, Object>> fileList = new ArrayList<>();
|
||||
for (FileInfo file : torrentInfo.getFiles()) {
|
||||
java.util.Map<String, Object> fileMap = new java.util.HashMap<>();
|
||||
fileMap.put("length", file.getLength());
|
||||
fileMap.put("path", file.getPath());
|
||||
fileList.add(fileMap);
|
||||
}
|
||||
infoMap.put("files", fileList);
|
||||
} else {
|
||||
// 单文件模式
|
||||
infoMap.put("length", torrentInfo.getLength());
|
||||
}
|
||||
|
||||
torrentMap.put("info", infoMap);
|
||||
|
||||
// 写入文件
|
||||
bos.writeDictionary(torrentMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供种子文件下载
|
||||
*
|
||||
* @param torrentFilePath 种子文件路径
|
||||
* @param downloadPath 下载保存路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void downloadTorrent(String torrentFilePath, String downloadPath) throws IOException {
|
||||
Path source = Paths.get(torrentFilePath);
|
||||
Path target = Paths.get(downloadPath);
|
||||
|
||||
if (!Files.exists(source)) {
|
||||
throw new FileNotFoundException("种子文件不存在: " + torrentFilePath);
|
||||
}
|
||||
|
||||
Files.copy(source, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析种子文件信息
|
||||
*
|
||||
* @param torrentFilePath 种子文件路径
|
||||
* @return 种子信息
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static TorrentInfo parseTorrent(String torrentFilePath) throws IOException {
|
||||
try (FileInputStream fis = new FileInputStream(torrentFilePath);
|
||||
BencodeInputStream bis = new BencodeInputStream(fis)) {
|
||||
|
||||
java.util.Map<String, Object> torrentMap = bis.readDictionary();
|
||||
TorrentInfo torrentInfo = new TorrentInfo();
|
||||
|
||||
torrentInfo.setAnnounce((String) torrentMap.get("announce"));
|
||||
|
||||
Object creationDate = torrentMap.get("creation date");
|
||||
if (creationDate instanceof Number) {
|
||||
torrentInfo.setCreationDate(((Number) creationDate).longValue());
|
||||
}
|
||||
|
||||
torrentInfo.setCreatedBy((String) torrentMap.get("created by"));
|
||||
|
||||
// 解析info部分
|
||||
java.util.Map<String, Object> infoMap = (java.util.Map<String, Object>) torrentMap.get("info");
|
||||
if (infoMap != null) {
|
||||
torrentInfo.setName((String) infoMap.get("name"));
|
||||
|
||||
Object pieceLength = infoMap.get("piece length");
|
||||
if (pieceLength instanceof Number) {
|
||||
torrentInfo.setPieceLength(((Number) pieceLength).intValue());
|
||||
}
|
||||
|
||||
torrentInfo.setPieces((byte[]) infoMap.get("pieces"));
|
||||
|
||||
Object length = infoMap.get("length");
|
||||
if (length instanceof Number) {
|
||||
torrentInfo.setLength(((Number) length).longValue());
|
||||
}
|
||||
|
||||
// 处理文件列表
|
||||
Object filesObj = infoMap.get("files");
|
||||
if (filesObj instanceof List) {
|
||||
List<java.util.Map<String, Object>> fileList =
|
||||
(List<java.util.Map<String, Object>>) filesObj;
|
||||
|
||||
List<FileInfo> files = new ArrayList<>();
|
||||
for (java.util.Map<String, Object> fileMap : fileList) {
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
|
||||
Object fileLength = fileMap.get("length");
|
||||
if (fileLength instanceof Number) {
|
||||
fileInfo.setLength(((Number) fileLength).longValue());
|
||||
}
|
||||
|
||||
fileInfo.setPath((List<String>) fileMap.get("path"));
|
||||
files.add(fileInfo);
|
||||
}
|
||||
torrentInfo.setFiles(files);
|
||||
}
|
||||
}
|
||||
|
||||
return torrentInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 种子信息类
|
||||
*/
|
||||
public static class TorrentInfo {
|
||||
private String announce;
|
||||
private long creationDate;
|
||||
private String createdBy;
|
||||
private String name;
|
||||
private long length;
|
||||
private int pieceLength;
|
||||
private byte[] pieces;
|
||||
private List<FileInfo> files;
|
||||
|
||||
// Getters and Setters
|
||||
public String getAnnounce() {
|
||||
return announce;
|
||||
}
|
||||
|
||||
public void setAnnounce(String announce) {
|
||||
this.announce = announce;
|
||||
}
|
||||
|
||||
public long getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
public void setCreationDate(long creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(long length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public int getPieceLength() {
|
||||
return pieceLength;
|
||||
}
|
||||
|
||||
public void setPieceLength(int pieceLength) {
|
||||
this.pieceLength = pieceLength;
|
||||
}
|
||||
|
||||
public byte[] getPieces() {
|
||||
return pieces;
|
||||
}
|
||||
|
||||
public void setPieces(byte[] pieces) {
|
||||
this.pieces = pieces;
|
||||
}
|
||||
|
||||
public List<FileInfo> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
public void setFiles(List<FileInfo> files) {
|
||||
this.files = files;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件信息类
|
||||
*/
|
||||
public static class FileInfo {
|
||||
private long length;
|
||||
private List<String> path;
|
||||
|
||||
// Getters and Setters
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(long length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public List<String> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(List<String> path) {
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// 创建种子文件
|
||||
BtTorrentUtil.createTorrent(
|
||||
"/path/to/your/file_or_directory",
|
||||
"http://tracker.example.com:6969/announce",
|
||||
"/path/to/output.torrent"
|
||||
);
|
||||
|
||||
// 解析种子文件
|
||||
TorrentInfo info = BtTorrentUtil.parseTorrent("/path/to/output.torrent");
|
||||
System.out.println("种子名称: " + info.getName());
|
||||
System.out.println("创建时间: " + new Date(info.getCreationDate() * 1000));
|
||||
|
||||
// 下载种子文件
|
||||
BtTorrentUtil.downloadTorrent(
|
||||
"/path/to/output.torrent",
|
||||
"/path/to/download/location.torrent"
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package com.unisinsight.project.util;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 种子文件工具类
|
||||
*/
|
||||
public class BtTorrentUtils {
|
||||
|
||||
private static final String BT_SCRIPT_PATH = "/var/lib/vdi/nodejs/bttorrent.sh";
|
||||
|
||||
private static final Long WAIT_START_TIME = 8000L;
|
||||
|
||||
/**
|
||||
* 制作种子并开始做种
|
||||
*
|
||||
* @param sourceFile 源文件路径(如 /data/file.iso)
|
||||
* @param torrentFile 生成的种子文件路径(如 /data/file.torrent)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean createAndSeed(String sourceFile, String torrentFile) {
|
||||
// 验证文件是否存在
|
||||
if (!new File(sourceFile).exists()) {
|
||||
System.err.println("源文件不存在: " + sourceFile);
|
||||
return false;
|
||||
}
|
||||
// 确保目标目录存在
|
||||
new File(torrentFile).getParentFile().mkdirs();
|
||||
return executeCommand("start", sourceFile, torrentFile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 停止指定文件的做种
|
||||
*
|
||||
* @param sourceFile 源文件路径(如 /data/file.iso)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean stopSeeding(String sourceFile) {
|
||||
return executeCommand("stop_path", sourceFile, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 执行 bttorrent.sh 脚本
|
||||
*/
|
||||
private static boolean executeCommand(String command, String arg1, String arg2) {
|
||||
try {
|
||||
// 构造命令
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"bash",
|
||||
BT_SCRIPT_PATH,
|
||||
command,
|
||||
arg1,
|
||||
arg2 != null ? arg2 : "" // 处理可选参数
|
||||
).redirectErrorStream(true);
|
||||
// 启动进程
|
||||
Process process = pb.start();
|
||||
// 启动新线程读取输出,避免阻塞
|
||||
new Thread(() -> {
|
||||
try {
|
||||
logProcessOutput(process);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
// 对于start命令,只要进程启动成功就返回true
|
||||
if ("start".equals(command)) {
|
||||
// 稍微等待一下看初始输出是否有错误
|
||||
Thread.sleep(WAIT_START_TIME);
|
||||
return process.isAlive(); // 如果进程还在运行,认为启动成功
|
||||
}
|
||||
// 对于stop命令,仍然等待完成
|
||||
return process.waitFor() == 0;
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印进程输出
|
||||
*/
|
||||
private static void logProcessOutput(Process process) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println("[BT输出] " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue