在我的端点中,我接收到格式为 Base64 的字符串形式的文件内容。 使用 SevenZip 库解压缩效果很好,没有任何问题。 但是执行完这行之后
archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(
new RandomAccessFile(file, "r")));
java 由于以下异常而无法删除文件:
java.nio.file.FileSystemException: myFile.RAR: The process cannot access the file because it is being used by another process
我尝试过使用 junrar 库,但 SevenZip 效果更好(支持 RAR5 并识别损坏程度较低的文件作为 junrar)。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding</artifactId>
<version>16.02-2.01</version>
</dependency>
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding-all-platforms</artifactId>
<version>16.02-2.01</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这是 dto:
public record UploadDto(
@NotNull
String name,
@NotNull
String data) {
}
这是具有逻辑的控制器:
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
@RestController
public class TestController {
private final Logger log = LoggerFactory.getLogger(TestController.class);
@PostMapping("/upload")
public void extractRar(@RequestBody UploadDto dto){
byte[] decodedBytes = Base64.getDecoder().decode(dto.data());
try {
String filePath = dto.name();
Files.write(Paths.get(filePath), decodedBytes);
log.info("File saved successfully to: " + filePath);
File file = new File(filePath);
IInArchive archive;
try {
archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(
new RandomAccessFile(file, "r")));
log.info(String.valueOf(archive.getNumberOfItems()));
} catch (SevenZipException | FileNotFoundException e) {
throw new RuntimeException(e);
}
archive.close();
// 1 method
Files.delete(Path.of(filePath));
// 2 method
if (file.delete()) {
log.info("file deleted successfully");
} else {
log.error("failed to delete the temporary file used for unzipping");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
请求正文示例:
{
"name": "myFile.RAR",
"data": "UmFyIRoHAM+QcwAADQAAAAAAAABTL3QgkC8AFAAAABQAAAACTeXQiWmKL1cdMAoAIAAAAG15RmlsZS50eHQAsAA/PXJhciBkYXRhIG1vY2sgaGVyZQ0KxD17AEAHAA=="
}
我尝试了两种方法来删除该文件,但似乎都不起作用。 另外,我没有找到任何使用字节数组或 InputStream 打开Archive 的方法。 如果我可以在提取内容后删除文件或提取内容而不在本地保存文件,那么问题就可以解决。 任何帮助或想法将不胜感激! 操作系统 Windows 10
网上找到的例子,关闭存档后关闭文件。
类似以下内容(根据您的需要,您可能需要单独尝试捕获 close() 调用):
@PostMapping("/upload")
public void extractRar(@RequestBody UploadDto dto){
byte[] decodedBytes = Base64.getDecoder().decode(dto.data());
try {
String filePath = dto.name();
Files.write(Paths.get(filePath), decodedBytes);
log.info("File saved successfully to: " + filePath);
File file = new File(filePath);
IInArchive archive;
RandomAccessFile randomAccessFile;
try {
randomAccessFile = new RandomAccessFile(file, "r");
archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
log.info(String.valueOf(archive.getNumberOfItems()));
} catch (SevenZipException | FileNotFoundException e) {
throw new RuntimeException(e);
}
archive.close();
randomAccessFile.close();
// 1 method
Files.delete(Path.of(filePath));
// 2 method
if (file.delete()) {
log.info("file deleted successfully");
} else {
log.error("failed to delete the temporary file used for unzipping");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}