提交代码
This commit is contained in:
parent
5525ca35c1
commit
52b7c71fca
@ -43,28 +43,15 @@ import com.yfd.platform.system.domain.SysDictionaryItems;
|
||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
||||
import com.yfd.platform.utils.StringUtils;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import com.github.junrar.Archive;
|
||||
import com.github.junrar.rarfile.FileHeader;
|
||||
import com.github.junrar.exception.RarException;
|
||||
import io.netty.handler.codec.compression.CompressionException;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@ -115,6 +102,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
|
||||
// 从数据库获取的压缩类型列表
|
||||
private List<String> compressSuffixes;
|
||||
private final Set<String> addedEntries = new HashSet<>();
|
||||
|
||||
/**********************************
|
||||
* 用途说明: 分页查询试验数据管理-文档内容
|
||||
@ -1167,13 +1155,18 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
}
|
||||
|
||||
Path zipPath = generateZipPath(sourcePaths.get(0));
|
||||
addedEntries.clear(); // 清空历史记录
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipPath))) {
|
||||
zipOut.setLevel(Deflater.DEFAULT_COMPRESSION);
|
||||
|
||||
for (Path sourcePath : sourcePaths) {
|
||||
if (Files.isDirectory(sourcePath)) {
|
||||
addDirectoryToZip(sourcePath, zipOut, sourcePath.getFileName().toString());
|
||||
// 使用唯一化的 baseDir(例如目录名)
|
||||
String baseDir = sourcePath.getFileName().toString();
|
||||
addDirectoryToZip(sourcePath, zipOut, baseDir);
|
||||
} else {
|
||||
// 文件直接添加到根目录,或指定唯一子目录
|
||||
addFileToZip(sourcePath, zipOut, "");
|
||||
}
|
||||
}
|
||||
@ -1188,23 +1181,46 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
}
|
||||
|
||||
private void addDirectoryToZip(Path dir, ZipOutputStream zipOut, String baseDir) throws IOException {
|
||||
final Path sourceDir = dir;
|
||||
|
||||
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
String entryName = baseDir + "/" + dir.relativize(dir).toString().replace("\\", "/") + "/";
|
||||
ZipEntry entry = new ZipEntry(entryName);
|
||||
zipOut.putNextEntry(entry);
|
||||
zipOut.closeEntry();
|
||||
public FileVisitResult preVisitDirectory(Path currentDir, BasicFileAttributes attrs) throws IOException {
|
||||
// 跳过源目录自身(由外部显式添加)
|
||||
if (currentDir.equals(sourceDir)) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
// 生成相对路径的条目名称
|
||||
Path relativePath = sourceDir.relativize(currentDir);
|
||||
String entryName = baseDir + "/" + relativePath.toString().replace("\\", "/") + "/";
|
||||
|
||||
// 确保条目唯一性
|
||||
addUniqueDirectoryEntry(entryName, zipOut);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
String entryName = baseDir + "/" + dir.relativize(file).toString().replace("\\", "/");
|
||||
Path relativePath = sourceDir.relativize(file);
|
||||
String entryName = baseDir + "/" + relativePath.toString().replace("\\", "/");
|
||||
addFileEntry(file, entryName, zipOut);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
// 显式添加根目录条目(确保至少存在一个目录条目)
|
||||
String rootEntry = baseDir + "/";
|
||||
addUniqueDirectoryEntry(rootEntry, zipOut);
|
||||
}
|
||||
|
||||
private void addUniqueDirectoryEntry(String entryName, ZipOutputStream zipOut) throws IOException {
|
||||
if (!addedEntries.contains(entryName)) {
|
||||
ZipEntry entry = new ZipEntry(entryName);
|
||||
zipOut.putNextEntry(entry);
|
||||
zipOut.closeEntry();
|
||||
addedEntries.add(entryName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addFileToZip(Path file, ZipOutputStream zipOut, String baseDir) throws IOException {
|
||||
@ -1213,6 +1229,11 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
}
|
||||
|
||||
private void addFileEntry(Path file, String entryName, ZipOutputStream zipOut) throws IOException {
|
||||
if (addedEntries.contains(entryName)) {
|
||||
LOGGER.warn("跳过重复条目: {}", entryName);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.debug("添加文件条目: {} (大小: {} 字节)", entryName, Files.size(file));
|
||||
ZipEntry entry = new ZipEntry(entryName);
|
||||
entry.setSize(Files.size(file));
|
||||
@ -1228,6 +1249,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
}
|
||||
|
||||
zipOut.closeEntry();
|
||||
addedEntries.add(entryName);
|
||||
}
|
||||
|
||||
private Path generateZipPath(Path sourcePath) {
|
||||
@ -1247,7 +1269,8 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
ZipEntry entry = entries.nextElement();
|
||||
try (InputStream is = zipFile.getInputStream(entry)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
while (is.read(buffer) != -1) {} // 读取条目内容
|
||||
while (is.read(buffer) != -1) {
|
||||
} // 读取条目内容
|
||||
}
|
||||
}
|
||||
|
||||
@ -1262,7 +1285,8 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
private void deleteQuietly(Path path) {
|
||||
try {
|
||||
Files.deleteIfExists(path);
|
||||
} catch (IOException ignored) {}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1277,13 +1301,6 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ================== TAR.GZ格式压缩实现 ==================
|
||||
private boolean compressToTarGz(List<Path> sourcePaths) throws IOException {
|
||||
boolean success = true;
|
||||
@ -1420,7 +1437,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
|
||||
// 1. 获取压缩包记录
|
||||
TsFiles zipFileRecord = tsFilesMapper.selectById(id);
|
||||
String zipName = zipFileRecord.getFileName(); // 示例:222
|
||||
String zipName = getFileNameWithoutExtension(zipFileRecord.getFileName()); // 示例:222
|
||||
try {
|
||||
// 2. 判断压缩包类型(单文件还是文件夹)
|
||||
Path zipFilePath = Paths.get(storageSourceConfig.getValue(), zipFileRecord.getWorkPath(), zipFileRecord.getFileName());
|
||||
@ -1429,12 +1446,8 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
// // 4. 构建解压目标路径
|
||||
Path destRoot;
|
||||
if (hasFolder) {
|
||||
// 动态去掉 .zip 后缀(仅用于路径构建)
|
||||
String folderName = zipName.toLowerCase().endsWith(".zip")
|
||||
? zipName.substring(0, zipName.length() - 4)
|
||||
: zipName;
|
||||
// 如果有文件夹,创建子目录(如 E:/yun/333/222/)
|
||||
destRoot = Paths.get(storageSourceConfig.getValue(), decompressionPath, folderName);
|
||||
destRoot = Paths.get(storageSourceConfig.getValue(), decompressionPath, zipName);
|
||||
} else {
|
||||
// 如果只有文件,直接解压到目标目录(如 E:/yun/333/)
|
||||
destRoot = Paths.get(storageSourceConfig.getValue(), decompressionPath);
|
||||
@ -1460,7 +1473,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
);
|
||||
String rootFolderId = rootFolder.getId();
|
||||
|
||||
// 7. 处理子内容(路径从/333/222/开始)
|
||||
// 7. 处理子内容(路径从/333/222/开始) 关键点 所有的文件夹都是上级路径 文件是上级路径加名称
|
||||
processFolderContents(
|
||||
unzippedRoot,
|
||||
rootFolderId,
|
||||
@ -1577,7 +1590,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
folderRecord.setTaskId(taskId);
|
||||
folderRecord.setParentId(parentId); // 父ID是222的ID
|
||||
folderRecord.setFileName(child.getName());
|
||||
folderRecord.setWorkPath(childWorkPath); // /333/222/555/
|
||||
folderRecord.setWorkPath(folderWorkPath); // /333/222/555/
|
||||
folderRecord.setIsFile("FOLDER");
|
||||
folderRecord.setFileSize("0");
|
||||
folderRecord.setUploadTime(new Timestamp(System.currentTimeMillis()));
|
||||
@ -1587,7 +1600,7 @@ public class TsFilesServiceImpl extends ServiceImpl<TsFilesMapper, TsFiles> impl
|
||||
processFolderContents(
|
||||
child,
|
||||
folderRecord.getId(),
|
||||
folderWorkPath,
|
||||
childWorkPath,
|
||||
taskId,
|
||||
nodeId,
|
||||
uploader
|
||||
|
Loading…
Reference in New Issue
Block a user