This commit is contained in:
@@ -5,8 +5,14 @@ import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* 7z 解压器
|
||||
*
|
||||
* @author 夜雨
|
||||
* @version 2024-06-30 19:42
|
||||
*/
|
||||
@@ -14,44 +20,98 @@ public class Z7Decompressor extends Decompressor {
|
||||
|
||||
@Override
|
||||
public void run(File fromFile, String toPath) throws Exception {
|
||||
toPath = new File(toPath).getAbsolutePath() + SEP;
|
||||
|
||||
int total = 0;
|
||||
if (progressCallback != null) {
|
||||
SevenZFile file = SevenZFile.builder().setFile(fromFile).get();
|
||||
try (file) {
|
||||
while (file.getNextEntry() != null) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
initByteProgress(readTotalSize(fromFile));
|
||||
try {
|
||||
super.run(fromFile, toPath);
|
||||
} finally {
|
||||
resetProgress();
|
||||
}
|
||||
SevenZFile file = SevenZFile.builder().setFile(fromFile).get();
|
||||
SevenZArchiveEntry entry;
|
||||
for (int i = 0; (entry = file.getNextEntry()) != null; i++) {
|
||||
if (entry.isDirectory()) {
|
||||
IO.dir(IO.fitPath(toPath) + entry.getName());
|
||||
} else {
|
||||
File toFile = IO.file(toPath + entry.getName());
|
||||
byte[] buffer = new byte[(int) entry.getSize()];
|
||||
file.read(buffer, 0, buffer.length);
|
||||
IO.toFile(toFile, buffer);
|
||||
}
|
||||
|
||||
if (fileCallback != null) {
|
||||
fileCallback.handler(toFile);
|
||||
@Override
|
||||
public void run(InputStream fromStream, String toPath) throws Exception {
|
||||
Path tempFile = writeTempFile(fromStream);
|
||||
try (SevenZFile file = SevenZFile.builder().setFile(tempFile.toFile()).get()) {
|
||||
SevenZArchiveEntry entry;
|
||||
boolean processed = false;
|
||||
while ((entry = file.getNextEntry()) != null) {
|
||||
if (entry.isDirectory()) {
|
||||
IO.dir(IO.fitPath(toPath) + entry.getName());
|
||||
} else {
|
||||
File toFile = IO.file(IO.fitPath(toPath) + entry.getName());
|
||||
try (OutputStream outputStream = IO.getOutputStream(toFile)) {
|
||||
copySevenZEntry(file, entry, outputStream);
|
||||
outputStream.flush();
|
||||
}
|
||||
handleFile(toFile);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
if (isPause) {
|
||||
synchronized (pauseLock) {
|
||||
pauseLock.wait();
|
||||
}
|
||||
if (processed) {
|
||||
finishProgress();
|
||||
}
|
||||
if (progressCallback != null && total != -1) {
|
||||
progressCallback.handler(1D * i / total);
|
||||
}
|
||||
if (isInterrupt) {
|
||||
} finally {
|
||||
Files.deleteIfExists(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将输入流写入临时文件
|
||||
*
|
||||
* @param fromStream 输入流
|
||||
* @return 临时文件路径
|
||||
* @throws Exception 写入失败
|
||||
*/
|
||||
private Path writeTempFile(InputStream fromStream) throws Exception {
|
||||
Path tempFile = Files.createTempFile("timi-compress-", ".7z");
|
||||
try (OutputStream outputStream = Files.newOutputStream(tempFile)) {
|
||||
transfer(fromStream, outputStream, false);
|
||||
outputStream.flush();
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制当前 7z 条目数据
|
||||
*
|
||||
* @param file 7z 文件
|
||||
* @param entry 当前条目
|
||||
* @param toStream 输出流
|
||||
* @throws Exception 复制失败
|
||||
*/
|
||||
private void copySevenZEntry(SevenZFile file, SevenZArchiveEntry entry, OutputStream toStream) throws Exception {
|
||||
byte[] buffer = new byte[8192];
|
||||
long remain = entry.getSize();
|
||||
while (0 < remain) {
|
||||
awaitIfPaused();
|
||||
ensureRunning();
|
||||
int length = file.read(buffer, 0, (int) Math.min(buffer.length, remain));
|
||||
if (length < 0) {
|
||||
break;
|
||||
}
|
||||
toStream.write(buffer, 0, length);
|
||||
remain -= length;
|
||||
handleTransferred(length);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取压缩包解压总字节数
|
||||
*
|
||||
* @param fromFile 压缩文件
|
||||
* @return 总字节数
|
||||
* @throws Exception 读取失败
|
||||
*/
|
||||
private long readTotalSize(File fromFile) throws Exception {
|
||||
long totalSize = 0L;
|
||||
try (SevenZFile file = SevenZFile.builder().setFile(fromFile).get()) {
|
||||
SevenZArchiveEntry entry;
|
||||
while ((entry = file.getNextEntry()) != null) {
|
||||
if (!entry.isDirectory()) {
|
||||
totalSize += entry.getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user