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