Java解析zip文件,并识别压缩包里面的文件转换成可操作的IO流方式
作者:BestTomDoG
这篇文章主要介绍了Java解析zip文件,并识别压缩包里面的文件转换成可操作的IO流方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Java解析zip文件,并识别压缩包里面的文件转换成可操作的IO流
前几天项目遇到一个棘手的问题,
批量上传人员的证件照,因为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+"条数据"); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。