前言
目前手中有個專案,需要做到用戶打包圖片上傳處理的邏輯,這個時候,就需要用到一個JAVA的壓縮/解壓庫Apache Commons Compress ,
- 從壓縮檔案中逐個讀取檔案(廢話,肯定從里面讀啦),
- 讀取檔案的檔案名進行業務邏輯判斷(檔案名跟業務編號有關),
- 上傳之后回傳一個資訊說哪些成功、哪些失敗、哪些例外或沒有權限,
WHats Apache Commons Compress?
Apache Commons Compress,Compress是ApacheCommons提供壓縮、解壓縮檔案的類別庫,定義了一個用于處理ar,cpio,Unix dump,tar,zip,gzip,XZ,Pack200,bzip2、7z,arj,lzma,snappy,DEFLATE,lz4,Brotli,Zstandard,DEFLATE64和Z檔案的API ,非常強大,
官網 http://commons.apache.org/proper/commons-compress/
POM.xml
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.20</version>
</dependency>
核心代碼
假設檔案以及成功上傳到目標檔案夾(本文不涉及上傳,只講解解壓)

ArchiveInputStream archiveInputStream = factory.createArchiveInputStream(ArchiveStreamFactory.ZIP,inputStream);
代表解壓ZIP檔案,也支持一下檔案:

業務代碼:
public ReturnT importImage(String filename,Integer roleId,Integer userId){
List<String> resultList = new ArrayList<>(24);
File archiveFile = new File(storageService.getPathString()+filename);
File outputDir = new File(storageService.getPathString()+userId);
// 指定檔案所用字符集,這里以UTF-8為例
ArchiveStreamFactory factory = new ArchiveStreamFactory("UTF-8");
try {
InputStream inputStream = new FileInputStream(archiveFile);
//暫定解壓ZIP檔案
ArchiveInputStream archiveInputStream = factory.createArchiveInputStream(ArchiveStreamFactory.ZIP,inputStream);
ArchiveEntry archiveEntry = null;
OutputStream outputStream;
File outputFile;
byte[] buffer = new byte[512];
int bytesRead;
while ((archiveEntry = archiveInputStream.getNextEntry()) != null) {
//獲取完整檔案名
String filenameInZip =archiveEntry.getName();
//從最后一.開始切割獲取證書編號
String certNumber = filenameInZip.substring(0,filenameInZip.lastIndexOf("."));
Cert cert = certMapper.selectOne(new QueryWrapper<Cert>().eq("cert_number",certNumber));
if(cert==null){
log.info("unzip-證書不存在:{} 證書上傳者roleId{} userId:{}",certNumber,roleId,userId);
resultList.add(certNumber+":證書不存在");
}else if(roleId==9|| userId.equals(cert.getUserId())){
log.info("unzip-證書上傳成功:{} 證書上傳者roleId{} userId:{}",certNumber,roleId,userId);
//判斷檔案對應的certNumber是否擁有權限
outputFile = new File(outputDir, filenameInZip);
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
outputStream = new FileOutputStream(outputFile);
// 進行資料拷貝
while ((bytesRead = archiveInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
cert.setCertImg(userId+"/"+filenameInZip);
cert.setUpdateTime(new Date());
certMapper.updateById(cert);
resultList.add(certNumber+":證書上傳成功");
}else{
log.info("unzip-權限錯誤:{} 證書上傳者roleId{} userId:{}",certNumber,roleId,userId);
resultList.add(certNumber+":權限錯誤");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return ReturnT.SUCCESS(resultList);
}
效果查看
前端可以顯示什么上傳成功

上傳目錄可以看到成功的檔案已經解壓,其它不需要處理的檔案已經忽略,

關于ArchiveStreamFactory
關于ArchiveStreamFactory的資訊,可以在一下javadoc中找到,包含解壓zip壓縮包和壓縮成zip安裝包,
#ClassInfo
public class ArchiveStreamFactory
extends java.lang.Object
implements ArchiveStreamProvider
#Description:
Factory to create Archive[In|Out]putStreams from names or the first bytes of the InputStream. In order to add other implementations, you should extend ArchiveStreamFactory and override the appropriate methods (and call their implementation from super of course).
### Compressing a ZIP-File:
final OutputStream out = Files.newOutputStream(output.toPath());
ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, out);
os.putArchiveEntry(new ZipArchiveEntry("testdata/test1.xml"));
IOUtils.copy(Files.newInputStream(file1.toPath()), os);
os.closeArchiveEntry();
os.putArchiveEntry(new ZipArchiveEntry("testdata/test2.xml"));
IOUtils.copy(Files.newInputStream(file2.toPath()), os);
os.closeArchiveEntry();
os.close();
### Decompressing a ZIP-File:
final InputStream is = Files.newInputStream(input.toPath());
ArchiveInputStream in = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP, is);
ZipArchiveEntry entry = (ZipArchiveEntry)in.getNextEntry();
OutputStream out = Files.newOutputStream(dir.toPath().resolve(entry.getName()));
IOUtils.copy(in, out);
out.close();
in.close();
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/239199.html
標籤:java
