业务需求:只获取压缩包中的一级目录(包含:有文件夹跳过,rar使用的7z)
读取异常处理
/**
* 系统异常类
* @author sgq
*/
public class ReadZipException extends Exception {
private static final long serialVersionUID = 1L;
public ReadZipException(String message) {
super(message);
}
public ReadZipException(String message, Throwable ex) {
super(message, ex);
}
public ReadZipException(Throwable ex) {
super(ex);
}
}
所需依赖
<!-- https://mvnrepository.com/artifact/ant/ant -->
<!--zip-->
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.junrar/junrar --> ===》可以获取最新依赖
<!-- 解压rar -->
<!--<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>4.0.0</version>
</dependency>-->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>java-unrar</artifactId>
<version>1.7.0-8</version>
</dependency>
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>0.7</version>
</dependency>
<!--7z-->
<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>
<--io流-->
<dependency>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
<version>2.0.1</version>
</dependency>
类文件
参考文章::点击
//导入的包
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.sevenzipjbinding.*;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class ReadZipFileUtils {
//加入了log日志
public static Logger LOG = LoggerFactory.getLogger(ReadZipFileUtils.class);
//获取压缩包中的大小和名称
public static List<Map<String, Object>> readZipFile(String path,String appPath) throws ReadZipException {
List<Map<String, Object>> list = new ArrayList<>();
try {
ZipEntry zipEntry;
File file = new File(path);
//判断文件是否存在,并且是zip格式的压缩包
if (file.exists() && file.getName().toLowerCase().endsWith(".zip")) {
//解决包内文件存在中文时的中文乱码问题
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(path), Charset.forName("GBK"))) {
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
//遇到文件夹就跳过
if (zipEntry.isDirectory()) {
LOG.warn("跳过目录:{}", zipEntry.getName());
continue;
} else {
Map<String, Object> map = new HashMap<>();
//获取具体的文件名称
String name = zipEntry.getName();
//如果带有 / 则是目录不添加
if (name.contains("/")) {
LOG.warn("文件没在根目录跳过:{}", name);
continue;
}
//获取文件的大小
long size = zipEntry.getSize();
long csize = zipEntry.getCompressedSize();
map.put("filename", name);
map.put("size", size);
map.put("csize", csize);
list.add(map);
}
}
}
//判断文件是否存在,并且是rar格式的压缩包
} else if (file.exists() && file.getName().toLowerCase().endsWith(".rar")) { //查看上传文件的后缀
if (!file.exists()) {
throw new RuntimeException(file.getPath() + "所指文件不存在");
}
RandomAccessFile randomAccessFile =null;
IInArchive inArchive = null;
try {
randomAccessFile =new RandomAccessFile(file,"r"); //只读
inArchive=SevenZip.openInArchive(null,new RandomAccessFileInStream(randomAccessFile));
for (int idx = 0; idx < inArchive.getNumberOfItems(); idx++) {
if (!(boolean) (((String)inArchive.getProperty(idx, PropID.PATH)).contains("\\"))){ //过滤掉文件夹
if ((boolean) (((String)inArchive.getProperty(idx, PropID.PATH)).contains("."))) { //防止最后一级为空文件夹
Map<String, Object> map = new HashMap<>();
//获取具体的文件名称
map.put("filename", inArchive.getProperty(idx, PropID.PATH)); //文件名称
map.put("size", inArchive.getProperty(idx, PropID.PACKED_SIZE));//大小
map.put("csize", inArchive.getProperty(idx, PropID.SIZE));//原始大小
list.add(map);
}
} else {
continue;
}
}
}
finally {
randomAccessFile.close();
}
}
} catch (Exception e) {
throw new ReadZipException("读取压缩文件错误:" + e.getMessage(), e);
}
return list;
}
}