前几天项目遇到一个棘手的问题,批量上传人员的证件照,因为java操作文件夹不好操作,最后决定把存放人员证件照的文件夹压缩成zip文件,通过java去解析,然后把里面的文件转成list集合,这里使用的jdk提供的 java.util.zip包
第一步:引入需要的maven依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
第二步:创建UnzipFileVo对象(文件的载体)
@Data
public class UnzipFileVo {
private MultipartFile file;
}
第三步:编写转换工具类
public class ZipUtil {
public static List<UnzipFileVo> Ectract(MultipartFile multipartFile) throws IOException {
List<UnzipFileVo> list= new ArrayList<>();
//获取文件输入流
InputStream input = multipartFile.getInputStream();
//获取ZIP输入流(一定要指定字符集Charset.forName("GBK")否则会报java.lang.IllegalArgumentException: MALFORMED)
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(input), Charset.forName("GBK"));
ZipFile zf = toFile(multipartFile);
//定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
ZipEntry ze = null;
//循环遍历
while ((ze =zipInputStream.getNextEntry())!= null) {
InputStream is = zf.getInputStream(ze);
UnzipFileVo unzipFileVo = new UnzipFileVo();
unzipFileVo.setFile(getMultipartFile(is,ze.getName()));
list.add(unzipFileVo);
}
//一定记得关闭流
zipInputStream.closeEntry();
input.close();
return list;
}
/**
* 获取封装得MultipartFile
*
* @param inputStream inputStream
* @param fileName fileName
* @return MultipartFile
*/
public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
FileItem fileItem = createFileItem(inputStream, fileName);
//CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
return new CommonsMultipartFile(fileItem);
}
private static ZipFile toFile(MultipartFile multipartFile) throws IOException {
if (multipartFile == null || multipartFile.getSize() <= 0) {
return null;
}
File file = multipartFileToFile(multipartFile);
if (file == null || !file.exists()) {
return null;
}
ZipFile zipFile = new ZipFile(file, Charset.forName("GBK"));
return zipFile;
}
private static File multipartFileToFile(MultipartFile multipartFile) {
File file = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = multipartFile.getInputStream();
file = new File(multipartFile.getOriginalFilename());
outputStream = new FileOutputStream(file);
write(inputStream, outputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
public static void write(InputStream inputStream, OutputStream outputStream) {
byte[] buffer = new byte[4096];
try {
int count = inputStream.read(buffer, 0, buffer.length);
while (count != -1) {
outputStream.write(buffer, 0, count);
count = inputStream.read(buffer, 0, buffer.length);
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* FileItem类对象创建
*
* @param inputStream inputStream
* @param fileName fileName
* @return FileItem
*/
public static FileItem createFileItem(InputStream inputStream, String fileName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "file";
FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
OutputStream os = null;
//使用输出流输出输入流的字节
try {
os = item.getOutputStream();
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
inputStream.close();
} catch (IOException e) {
throw new IllegalArgumentException("文件上传失败");
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
return item;
}
}
第四步:调用工具
@PostMapping("/UploadManagerPhoto")
public ActionResult uploadManagerPhoto(MultipartFile file) throws IOException {
if(Objects.isNull(file) || file.isEmpty()) {//验证文件是否为空
return ActionResult.fail("上传文件为空或不存在");
}
List<UnzipFileVo> unzipFileVoList = UnZipUtil.Ectract(file);
List<UnzipFileVo> collect = unzipFileVoList.stream().filter(item -> item.getFile().getOriginalFilename().contains(".") && item.getFile().getSize() > 0).collect(Collectors.toList());//获取zip文件里面的文件,并组装到新的List对象//过滤文件夹
//上面就是把zip压缩包的内容转换称了文件流集合,下面可根据自己的业务对文件进行操作
int sum = 0;
for (int i = 0; i < collect.size(); i++) {
//这是我自己封装的上传方法,大家可以根据自己的实际情况对文件进行操作
UploaderVO uploaderVO = fileService.uploader("document", collect.get(i).getFile());//调取上传方法,返回上传成功对象
sum++;
}
return ActionResult.success("解析zip成功,成功上传"+sum+"条数据");
}
不懂的可以私信