Java文件上传解压
目录结构
工具类
枚举
定义文件类型
public enum FileType {
// 未知
UNKNOWN,
// 压缩文件
ZIP, RAR, _7Z, TAR, GZ, TAR_GZ, BZ2, TAR_BZ2,
// 位图文件
BMP, PNG, JPG, JPEG,
// 矢量图文件
SVG,
// 影音文件
AVI, MP4, MP3, AAR, OGG, WAV, WAVE
}
为了避免文件被修改后缀,所以这里创建了一个获取文件的真实类型工具类
import com.zipfile.zipenum.FileType;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@Component
public class fileTypes {
public static FileType getFileType(InputStream inputStream){
// FileInputStream inputStream =null;
try{
// inputStream = new FileInputStream(file);
byte[] head = new byte[4];
if (-1 == inputStream.read(head)) {
return FileType.UNKNOWN;
}
int headHex = 0;
for (byte b : head) {
headHex <<= 8;
headHex |= b;
}
switch (headHex) {
case 0x504B0304:
return FileType.ZIP;
case 0x776f7264:
return FileType.TAR;
case -0x51:
return FileType._7Z;
case 0x425a6839:
return FileType.BZ2;
case -0x74f7f8:
return FileType.GZ;
case 0x52617221:
return FileType.RAR;
default:
return FileType.UNKNOWN;
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(inputStream!=null){
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return FileType.UNKNOWN;
}
解压压缩包的工具类
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
//@Component
public class decompression {
/**
* 解压缩tar文件
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompressTar(File file, String targetPath, boolean delete) {
try (FileInputStream fis = new FileInputStream(file);
TarArchiveInputStream tarInputStream = new TarArchiveInputStream(fis)) {
// 创建输出目录
Path outputDir = Paths.get(targetPath);
if (!Files.exists(outputDir)) {
Files.createDirectories(outputDir);
}
TarArchiveEntry entry;
while ((entry = tarInputStream.getNextTarEntry()) != null) {
Path entryPath = outputDir.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(entryPath); // 创建子目录
} else {
Files.createDirectories(entryPath.getParent()); // 确保父目录存在
try (OutputStream fos = Files.newOutputStream(entryPath)) {
byte[] buffer = new byte[2048];
int count;
while ((count = tarInputStream.read(buffer)) != -1) {
fos.write(buffer, 0, count);
}
}
}
}
// 如果需要删除原始文件
if (delete) {
Files.delete(file.toPath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解压缩7z文件
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
/**
* 解压 7z 文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompress7Z(File file, String targetPath, boolean delete) {
try (SevenZFile sevenZFile = new SevenZFile(file)) { // 自动关闭资源
// 创建输出目录
Path outputDir = Paths.get(targetPath);
if (!Files.exists(outputDir)) {
Files.createDirectories(outputDir);
}
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
Path entryPath = outputDir.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(entryPath); // 创建子目录
} else {
Files.createDirectories(entryPath.getParent()); // 确保父目录存在
try (OutputStream outputStream = new FileOutputStream(entryPath.toFile())) {
byte[] buffer = new byte[2048];
int len;
while ((len = sevenZFile.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
}
}
}
// 删除原始文件(可选)
if (delete) {
Files.delete(file.toPath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解压 RAR 文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompressRAR(File file, String targetPath, boolean delete) {
try (Archive archive = new Archive(file)) { // 自动关闭资源
// 创建输出目录
Path outputDir = Paths.get(targetPath);
if (!Files.exists(outputDir)) {
Files.createDirectories(outputDir);
}
FileHeader fileHeader;
while ((fileHeader = archive.nextFileHeader()) != null) {
String fileName = fileHeader.getFileNameString().trim();
Path filePath = outputDir.resolve(fileName);
if (fileHeader.isDirectory()) {
Files.createDirectories(filePath); // 创建子目录
} else {
Files.createDirectories(filePath.getParent()); // 确保父目录存在
try (OutputStream outputStream = new FileOutputStream(filePath.toFile())) {
archive.extractFile(fileHeader, outputStream);
}
}
}
// 如果需要删除原始文件
if (delete) {
Files.delete(file.toPath());
}
} catch (RarException | IOException e) {
e.printStackTrace();
}
}
/**
* 解压 ZIP 文件
*
* @param file ZIP 文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompressZIP(File file, String targetPath, boolean delete) {
try (InputStream fis = Files.newInputStream(file.toPath());
ZipInputStream zipInputStream = new ZipInputStream(fis)) {
// 创建输出目录
Path outputDir = Paths.get(targetPath);
if (!Files.exists(outputDir)) {
Files.createDirectories(outputDir);
}
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
Path entryPath = outputDir.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(entryPath); // 创建子目录
} else {
Files.createDirectories(entryPath.getParent()); // 确保父目录存在
try (FileOutputStream fos = new FileOutputStream(entryPath.toFile())) {
byte[] buffer = new byte[2048];
int len;
while ((len = zipInputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
}
zipInputStream.closeEntry();
}
// 如果需要删除原始文件
if (delete) {
Files.delete(file.toPath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
控制层
这里使用接口的方式,接受前端传过来的文件
import com.zipfile.service.ZipService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@RestController
@RequestMapping("zipUpload/")
public class ZipController {
@Autowired
private ZipService zipService;
@PostMapping("upload")
public void zipUpload(@RequestParam("file") MultipartFile file) throws IOException {
zipService.upload(file);
}
}
实现类
import com.zipfile.decompression.decompression;
import com.zipfile.util.fileTypes;
import com.zipfile.zipenum.FileType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import static com.zipfile.zipenum.FileType.ZIP;
@Service
public class ZipServiceImpl implements ZipService {
@Autowired
private fileTypes fileTypes;
@Override
public void upload(MultipartFile file) throws IOException {
FileType fileType = fileTypes.getFileType(file.getInputStream());
System.out.println(fileType);
if (fileType == ZIP){
// 创建临时文件
File tempFile = convertToFile(file);
decompression.decompressZIP(tempFile,"E:\\",true);
}
}
private File convertToFile(MultipartFile file) throws IOException {
// 获取文件的原始文件名
String originalFilename = file.getOriginalFilename();
if (originalFilename == null) {
throw new IOException("文件名为空!");
}
// 创建临时文件
String prefix = originalFilename.substring(0, originalFilename.lastIndexOf('.'));
String suffix = originalFilename.substring(originalFilename.lastIndexOf('.'));
File tempFile = File.createTempFile(prefix, suffix);
// 将 MultipartFile 的数据写入临时文件
file.transferTo(tempFile);
return tempFile;
}
}
依赖包
这是用到的依赖包
<!-- tar 解压-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.23.0</version>
</dependency>
<!--rar解压-->
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>7.5.4</version> <!-- 请根据最新版本选择 -->
</dependency>