v0.0.1
CI/CD / build-deploy (pull_request) Failing after 1m31s

This commit is contained in:
Timi
2026-04-01 14:09:24 +08:00
parent 47f1c9520e
commit afcc902cbf
20 changed files with 986 additions and 396 deletions
@@ -0,0 +1,238 @@
package com.imyeyu.compress;
import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.utils.OS;
import lombok.Setter;
import java.io.File;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 抽象压缩执行器
*
* @author 夜雨
* @since 2024-06-30 18:09
*/
public abstract class AbstractRunner implements OS.FileSystem {
/** 文件处理回调 */
@Setter
protected CallbackArg<File> fileCallback;
/** 进度回调 */
@Setter
protected CallbackArg<Double> progressCallback;
/** 中断标记 */
protected boolean isInterrupt = false;
/** 暂停标记 */
protected boolean isPause = false;
/** 暂停锁 */
protected final Object pauseLock = new Object();
/** 总字节数 */
private long progressTotalBytes = -1L;
/** 当前已处理字节数 */
private long progressBytes = 0L;
/** 暂停任务 */
public void pause() {
isPause = true;
}
/** 恢复任务 */
public void start() {
isPause = false;
synchronized (pauseLock) {
pauseLock.notifyAll();
}
}
/** 中断任务 */
public void interrupt() {
isInterrupt = true;
}
/**
* 初始化字节进度
*
* @param totalBytes 总字节数
*/
protected void initByteProgress(long totalBytes) {
progressBytes = 0L;
progressTotalBytes = totalBytes;
}
/** 重置进度状态 */
protected void resetProgress() {
progressBytes = 0L;
progressTotalBytes = -1L;
}
/**
* 执行暂停检查
*
* @throws InterruptedException 等待恢复时被中断
*/
protected void awaitIfPaused() throws InterruptedException {
if (!isPause) {
return;
}
synchronized (pauseLock) {
while (isPause) {
pauseLock.wait();
}
}
}
/**
* 检查是否已经中断
*
* @throws IOException 操作已中断
*/
protected void ensureRunning() throws IOException {
if (isInterrupt) {
throw new IOException("操作已中断");
}
}
/**
* 触发文件回调
*
* @param file 当前处理的文件
*/
protected void handleFile(File file) {
if (fileCallback != null) {
fileCallback.handler(file);
}
}
/**
* 触发进度回调
*
* @param currentBytes 当前已处理字节数
* @param totalBytes 总字节数
*/
protected void handleProgress(long currentBytes, long totalBytes) {
if (progressCallback == null || totalBytes < 1L) {
return;
}
double progress = Math.min(1D, currentBytes * 1D / totalBytes);
progressCallback.handler(progress);
}
/**
* 增加已处理字节数并回调
*
* @param bytes 本次新增字节数
*/
protected void handleTransferred(long bytes) {
if (bytes < 1L) {
return;
}
progressBytes += bytes;
handleProgress(progressBytes, progressTotalBytes);
}
/** 将进度推进到完成态 */
protected void finishProgress() {
if (progressCallback != null) {
progressCallback.handler(1D);
}
}
/**
* 复制数据流并更新进度
*
* @param fromStream 输入流
* @param toStream 输出流
* @return 已复制字节数
* @throws Exception 复制失败
*/
protected long transfer(InputStream fromStream, OutputStream toStream) throws Exception {
return transfer(fromStream, toStream, true);
}
/**
* 复制数据流
*
* @param fromStream 输入流
* @param toStream 输出流
* @param countProgress 是否统计进度
* @return 已复制字节数
* @throws Exception 复制失败
*/
protected long transfer(InputStream fromStream, OutputStream toStream, boolean countProgress) throws Exception {
byte[] buffer = new byte[8192];
long total = 0L;
int length;
while ((length = fromStream.read(buffer)) != -1) {
awaitIfPaused();
ensureRunning();
toStream.write(buffer, 0, length);
total += length;
if (countProgress) {
handleTransferred(length);
}
}
return total;
}
/**
* 创建一个关闭时不关闭原始流的输入流包装
*
* @param inputStream 原始输入流
* @return 包装后的输入流
*/
protected InputStream nonClosing(InputStream inputStream) {
return new FilterInputStream(inputStream) {
@Override
public void close() {
}
};
}
/**
* 创建一个关闭时不关闭原始流的输出流包装
*
* @param outputStream 原始输出流
* @return 包装后的输出流
*/
protected OutputStream nonClosing(OutputStream outputStream) {
return new FilterOutputStream(outputStream) {
@Override
public void close() throws IOException {
flush();
}
};
}
/**
* 规范化归档条目名称
*
* @param entryName 条目名称
* @return 规范化后的名称
*/
protected String normalizeEntryName(String entryName) {
if (entryName == null || entryName.isBlank()) {
throw new IllegalArgumentException("条目名称不能为空");
}
String normalized = entryName.replace('\\', '/');
while (normalized.startsWith("/")) {
normalized = normalized.substring(1);
}
if (normalized.isBlank()) {
throw new IllegalArgumentException("条目名称不能为空");
}
return normalized;
}
}