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+"条数据"); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论