Java解析zip文件,并識別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式
Java解析zip文件,并識別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流
前幾天項目遇到一個棘手的問題,
批量上傳人員的證件照,因為java操作文件夾不好操作,
最后決定把存放人員證件照的文件夾壓縮成zip文件,
通過java去解析,然后把里面的文件轉(zhuǎn)成list集合,這里使用的jdk提供的 java.util.zip包
第一步
引入需要的maven依賴
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
第二步
創(chuàng)建UnzipFileVo對象(文件的載體)
@Data public class UnzipFileVo { private MultipartFile file; }
第三步
編寫轉(zhuǎn)換工具類
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,避免由于重復調(diào)用zipInputStream.getNextEntry造成的不必要的問題 ZipEntry ze = null; //循環(huán)遍歷 while ((ze =zipInputStream.getNextEntry())!= null) { InputStream is = zf.getInputStream(ze); UnzipFileVo unzipFileVo = new UnzipFileVo(); unzipFileVo.setFile(getMultipartFile(is,ze.getName())); list.add(unzipFileVo); } //一定記得關(guān)閉流 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類對象創(chuàng)建 * * @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; //使用輸出流輸出輸入流的字節(jié) 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; } }
第四步
調(diào)用工具
@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壓縮包的內(nèi)容轉(zhuǎn)換稱了文件流集合,下面可根據(jù)自己的業(yè)務(wù)對文件進行操作 int sum = 0; for (int i = 0; i < collect.size(); i++) { //這是我自己封裝的上傳方法,大家可以根據(jù)自己的實際情況對文件進行操作 UploaderVO uploaderVO = fileService.uploader("document", collect.get(i).getFile());//調(diào)取上傳方法,返回上傳成功對象 sum++; } return ActionResult.success("解析zip成功,成功上傳"+sum+"條數(shù)據(jù)"); }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Java中super的幾種用法并與this的區(qū)別
這篇文章主要介紹了Java中super的幾種用法并與this的區(qū)別,有需要的朋友可以參考一下2013-12-12SpringData JPA實體映射與關(guān)系映射的實現(xiàn)
Spring Data JPA作為Spring生態(tài)系統(tǒng)中的核心項目,通過JPA規(guī)范提供了優(yōu)雅而強大的實體映射與關(guān)系處理機制,下面就來介紹一下,感興趣的可以了解一下2025-04-04java構(gòu)建OAuth2授權(quán)服務(wù)器
本文主要介紹了java構(gòu)建OAuth2授權(quán)服務(wù)器,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2021-07-07淺談java中replace()和replaceAll()的區(qū)別
這篇文章主要介紹了java中replace()和replaceAll()的區(qū)別,兩者都是常用的替換字符的方法,感興趣的小伙伴們可以參考一下2015-11-11