博舍

java 打包zip文件打不开 java生成zip文件末端错误

java 打包zip文件打不开

简介

平时我们都是使用WinZip,2345好压等软件来操作zip文件,java也提供了ZipOutputStream,ZipEntry等API创建和解析zip文件。

压缩

importjava.io.BufferedInputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.util.Objects;importjava.util.zip.ZipEntry;importjava.util.zip.ZipOutputStream;publicclassClient{publicstaticvoidmain(String[]args){compressFileToZip("D:original_computesku-20140802","D:original_computesku-20140802.zip");}/***读取文件内容并压缩,既支持文件也支持文件夹**@paramfilePath文件路径*/privatestaticvoidcompressFileToZip(StringfilePath,StringzipFilePath){try(ZipOutputStreamzos=newZipOutputStream(newFileOutputStream(zipFilePath))){//递归的压缩文件夹和文件doCompress("",filePath,zos);//必须zos.finish();}catch(Exceptione){e.printStackTrace();}}privatestaticvoiddoCompress(StringparentFilePath,StringfilePath,ZipOutputStreamzos){FilesourceFile=newFile(filePath);if(!sourceFile.exists()){return;}StringzipEntryName=parentFilePath+"/"+sourceFile.getName();if(parentFilePath.isEmpty()){zipEntryName=sourceFile.getName();}if(sourceFile.isDirectory()){File[]childFiles=sourceFile.listFiles();if(Objects.isNull(childFiles)){return;}for(FilechildFile:childFiles){doCompress(zipEntryName,childFile.getAbsolutePath(),zos);}}else{intlen=-1;byte[]buf=newbyte[1024];try(InputStreaminput=newBufferedInputStream(newFileInputStream(sourceFile))){zos.putNextEntry(newZipEntry(zipEntryName));while((len=input.read(buf))!=-1){zos.write(buf,0,len);}}catch(Exceptione){e.printStackTrace();}}}}

生成的压缩文件为

每一个ZipEntry表示一个压缩子文件,如sku.html。注意,ZipEntry的name必须为目录名+文件名,如sku-20140802/sku/sku.html。

/***Thisclassimplementsanoutputstreamfilterforwritingfilesinthe*ZIPfileformat.Includessupportforbothcompressedanduncompressed*entries.**@authorDavidConnelly*@since1.1*/publicclassZipOutputStreamextendsDeflaterOutputStreamimplementsZipConstants{/***在写入文件内容之前写入一些zip格式相关的数据*/publicvoidputNextEntry(ZipEntrye)throwsIOException{ensureOpen();if(current!=null){closeEntry();//closepreviousentry}if(e.xdostime==-1){//bydefault,doNOTuseextendedtimestampsinextra//data,fornow.e.setTime(System.currentTimeMillis());}if(e.method==-1){e.method=method;//usedefaultmethod}//storesize,compressedsize,andcrc-32inLOCheadere.flag=0;switch(e.method){caseDEFLATED://storesize,compressedsize,andcrc-32indatadescriptor//immediatelyfollowingthecompressedentrydataif(e.size==-1||e.csize==-1||e.crc==-1)e.flag=8;break;caseSTORED://compressedsize,uncompressedsize,andcrc-32mustallbe//setforentriesusingSTOREDcompressionmethodif(e.size==-1){e.size=e.csize;}elseif(e.csize==-1){e.csize=e.size;}elseif(e.size!=e.csize){thrownewZipException("STOREDentrywherecompressed!=uncompressedsize");}if(e.size==-1||e.crc==-1){thrownewZipException("STOREDentrymissingsize,compressedsize,orcrc-32");}break;default:thrownewZipException("unsupportedcompressionmethod");}if(!names.add(e.name)){thrownewZipException("duplicateentry:"+e.name);}if(zc.isUTF8())e.flag|=USE_UTF8;current=newXEntry(e,written);xentries.add(current);writeLOC(current);}/***文件内容写入*/publicsynchronizedvoidwrite(byte[]b,intoff,intlen)throwsIOException{ensureOpen();if(offentry.size){thrownewZipException("attempttowritepastendofSTOREDentry");}out.write(b,off,len);break;default:thrownewZipException("invalidcompressionmethod");}crc.update(b,off,len);}/***文件内容写入之后写入zip格式相关的数据*/publicvoidfinish()throwsIOException{ensureOpen();if(finished){return;}if(current!=null){closeEntry();}//writecentraldirectorylongoff=written;for(XEntryxentry:xentries)writeCEN(xentry);writeEND(off,written-off);finished=true;}}

可以看到,ZipOutputStream也是扩展DeflaterOutputStream.

解压

importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;importjava.util.zip.ZipEntry;importjava.util.zip.ZipFile;importjava.util.zip.ZipInputStream;publicclassClient{publicstaticvoidmain(String[]args)throwsException{decompressFromZip("D:/original_compute/sku-20140802.zip","D:/original_compute/testzip/");}/***文件解压缩,支持文件和文件夹的解压**@paramzipFilePath压缩包路径*@paramdestFilePath解压路径*/privatestaticvoiddecompressFromZip(StringzipFilePath,StringdestFilePath){Filefile=newFile(zipFilePath);try(ZipFilezipFile=newZipFile(file);ZipInputStreamzis=newZipInputStream(newFileInputStream(file))){ZipEntryzipEntry=null;while((zipEntry=zis.getNextEntry())!=null){StringfileName=destFilePath+"/"+zipEntry.getName();FileentryFile=newFile(fileName);if(zipEntry.isDirectory()){//创建文件夹entryFile.mkdir();}else{//创建文件之前必须保证父文件夹存在if(!entryFile.getParentFile().exists()){entryFile.getParentFile().mkdirs();}//创建文件entryFile.createNewFile();}try(InputStreaminput=zipFile.getInputStream(zipEntry);OutputStreamoutput=newFileOutputStream(entryFile)){intlen=-1;byte[]buf=newbyte[1024];while((len=input.read(buf))!=-1){output.write(buf,0,len);}}}}catch(Exceptione){e.printStackTrace();}}}

解压主要就是要获取到所有的压缩子文件,就是ZipEntry,将每一个ZipEntry重新生成文件或文件夹,生成文件时要确保父文件夹已经存在。

最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,springcloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友点击这里即可

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇