如何用Java创build一个zip文件

我有一个dynamic的文本文件,根据用户的查询从数据库中select内容。 我必须将这些内容写入一个文本文件,并将其压缩到一个servlet文件夹中。 我应该怎么做?

看看这个例子:

StringBuilder sb = new StringBuilder(); sb.append("Test String"); File f = new File("d:\\test.zip"); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f)); ZipEntry e = new ZipEntry("mytext.txt"); out.putNextEntry(e); byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length); out.closeEntry(); out.close(); 

这将创build一个位于D:“test.zip”根目录的Zip文件,它将包含一个名为“mytext.txt”的文件。 当然,你可以添加更多的zip条目,并指定一个子目录,如:

 ZipEntry e = new ZipEntry("folderName/mytext.txt"); 

你可以在这里find更多关于java压缩的信息:

http://www.oracle.com/technetwork/articles/java/compress-1565076.html

Java 7内置了ZipFileSystem,可用于从zip文件创build,写入和读取文件。

Java Doc:ZipFileSystem提供程序

 Map<String, String> env = new HashMap<>(); env.put("create", "true"); URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip"); try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) { Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt"); Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt"); // copy a file into the zip file Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); } 

要编写ZIP文件,请使用ZipOutputStream。 对于要放入ZIP文件的每个条目,创build一个ZipEntry对象。 您将文件名传递给ZipEntry构造函数; 它设置其他参数,如文件date和解压缩方法。 如果你喜欢,你可以覆盖这些设置。 然后,调用ZipOutputStream的putNextEntry方法开始写入新文件。 将文件数据发送到ZIPstream。 完成后,调用closeEntry。 重复所有你想存储的文件。 这是一个代码框架:

 FileOutputStream fout = new FileOutputStream("test.zip"); ZipOutputStream zout = new ZipOutputStream(fout); for all files { ZipEntry ze = new ZipEntry(filename); zout.putNextEntry(ze); send data to zout; zout.closeEntry(); } zout.close(); 
 public static void main(String args[]) { omtZip("res/", "omt.zip"); } public static void omtZip(String path,String outputFile) { final int BUFFER = 2048; boolean isEntry = false; ArrayList<String> directoryList = new ArrayList<String>(); File f = new File(path); if(f.exists()) { try { FileOutputStream fos = new FileOutputStream(outputFile); ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos)); byte data[] = new byte[BUFFER]; if(f.isDirectory()) { //This is Directory do{ String directoryName = ""; if(directoryList.size() > 0) { directoryName = directoryList.get(0); System.out.println("Directory Name At 0 :"+directoryName); } String fullPath = path+directoryName; File fileList = null; if(directoryList.size() == 0) { //Main path (Root Directory) fileList = f; }else { //Child Directory fileList = new File(fullPath); } String[] filesName = fileList.list(); int totalFiles = filesName.length; for(int i = 0 ; i < totalFiles ; i++) { String name = filesName[i]; File filesOrDir = new File(fullPath+name); if(filesOrDir.isDirectory()) { System.out.println("New Directory Entry :"+directoryName+name+"/"); ZipEntry entry = new ZipEntry(directoryName+name+"/"); zos.putNextEntry(entry); isEntry = true; directoryList.add(directoryName+name+"/"); }else { System.out.println("New File Entry :"+directoryName+name); ZipEntry entry = new ZipEntry(directoryName+name); zos.putNextEntry(entry); isEntry = true; FileInputStream fileInputStream = new FileInputStream(filesOrDir); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER); int size = -1; while( (size = bufferedInputStream.read(data, 0, BUFFER)) != -1 ) { zos.write(data, 0, size); } bufferedInputStream.close(); } } if(directoryList.size() > 0 && directoryName.trim().length() > 0) { System.out.println("Directory removed :"+directoryName); directoryList.remove(0); } }while(directoryList.size() > 0); }else { //This is File //Zip this file System.out.println("Zip this file :"+f.getPath()); FileInputStream fis = new FileInputStream(f); BufferedInputStream bis = new BufferedInputStream(fis,BUFFER); ZipEntry entry = new ZipEntry(f.getName()); zos.putNextEntry(entry); isEntry = true; int size = -1 ; while(( size = bis.read(data,0,BUFFER)) != -1) { zos.write(data, 0, size); } } //CHECK IS THERE ANY ENTRY IN ZIP ? ----START if(isEntry) { zos.close(); }else { zos = null; System.out.println("No Entry Found in Zip"); } //CHECK IS THERE ANY ENTRY IN ZIP ? ----START }catch(Exception e) { e.printStackTrace(); } }else { System.out.println("File or Directory not found"); } } } 

java.util.zip包中包含用于从Java内部创buildZip文件的类。 那会做你想要的吗?

Zip4j完全使用java代码,没有任何本地代码的支持,这是什么使它更适合我。 Zip4j提供以下function:

  • 创build,添加,提取,更新,从Zip文件中删除文件
  • 读/写密码保护的Zip文件
  • 支持AES 128/256encryption
  • 支持标准Zipencryption
  • 支持Zip64格式
  • 支持Store(无压缩)和Deflate压缩方式
  • 从分割Zip文件创build或提取文件(例如:z01,z02,… zip)
  • 支持Unicode文件名
  • 进度监视器

CreatePasswordProtectedZipExample.java

 import java.io.File; import java.util.ArrayList; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.util.Zip4jConstants; public class CreatePasswordProtectedZipExample { public static void main(String[] args) { try { //This is name and path of zip file to be created ZipFile zipFile = new ZipFile("C:/temp/test.zip"); //Add files to be archived into zip file ArrayList<File> filesToAdd = new ArrayList<File>(); filesToAdd.add(new File("C:/temp/test1.txt")); filesToAdd.add(new File("C:/temp/test2.txt")); //Initiate Zip Parameters which define various properties ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to deflate compression //DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression //DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression //DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed //DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed //DEFLATE_LEVEL_ULTRA - Highest compression level but low speed parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); //Set the encryption flag to true parameters.setEncryptFiles(true); //Set the encryption method to AES Zip Encryption parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); //AES_STRENGTH_128 - For both encryption and decryption //AES_STRENGTH_192 - For decryption only //AES_STRENGTH_256 - For both encryption and decryption //Key strength 192 cannot be used for encryption. But if a zip file already has a //file encrypted with key strength of 192, then Zip4j can decrypt this file parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); //Set password parameters.setPassword("howtodoinjava"); //Now add files to the zip file zipFile.addFiles(filesToAdd, parameters); } catch (ZipException e) { e.printStackTrace(); } } } 

这是一个压缩整个目录 (包括子文件和子目录)的示例代码,它使用Java NIO的步行文件树function。

 import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipCompress { public static void compress(String dirPath) { Path sourceDir = Paths.get(dirPath); String zipFileName = dirPath.concat(".zip"); try { ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName)); Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) { try { Path targetFile = sourceDir.relativize(file); outputStream.putNextEntry(new ZipEntry(targetFile.toString())); byte[] bytes = Files.readAllBytes(file); outputStream.write(bytes, 0, bytes.length); outputStream.closeEntry(); } catch (IOException e) { e.printStackTrace(); } return FileVisitResult.CONTINUE; } }); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } 

要使用这个,只需打电话

 ZipCompress.compress("target/directoryToCompress"); 

你会得到一个zip文件directoryToCompress.zip

Spring启动控制器,压缩目录中的文件,并可以下载。

 @RequestMapping(value = "/files.zip") @ResponseBody byte[] filesZip() throws IOException { File dir = new File("./"); File[] filesArray = dir.listFiles(); if (filesArray == null || filesArray.length == 0) System.out.println(dir.getAbsolutePath() + " have no file!"); ByteArrayOutputStream bo = new ByteArrayOutputStream(); ZipOutputStream zipOut= new ZipOutputStream(bo); for(File xlsFile:filesArray){ if(!xlsFile.isFile())continue; ZipEntry zipEntry = new ZipEntry(xlsFile.getName()); zipOut.putNextEntry(zipEntry); zipOut.write(IOUtils.toByteArray(new FileInputStream(xlsFile))); zipOut.closeEntry(); } zipOut.close(); return bo.toByteArray(); } 

如果你想不使用软件解压缩更好使用此代码。 其他与PDF文件的代码发送手动解压缩错误

 byte[] buffer = new byte[1024]; try { FileOutputStream fos = new FileOutputStream("123.zip"); ZipOutputStream zos = new ZipOutputStream(fos); ZipEntry ze= new ZipEntry("file.pdf"); zos.putNextEntry(ze); FileInputStream in = new FileInputStream("file.pdf"); int len; while ((len = in.read(buffer)) > 0) { zos.write(buffer, 0, len); } in.close(); zos.closeEntry(); zos.close(); } catch(IOException ex) { ex.printStackTrace(); } 

由于我花了一段时间才弄明白,我认为使用Java 7+ ZipFileSystem发布我的解决scheme会有所帮助

  openZip(runFile); addToZip(filepath); //loop construct; zipfs.close(); private void openZip(File runFile) throws IOException { Map<String, String> env = new HashMap<>(); env.put("create", "true"); env.put("encoding", "UTF-8"); Files.deleteIfExists(runFile.toPath()); zipfs = FileSystems.newFileSystem(URI.create("jar:" + runFile.toURI().toString()), env); } private void addToZip(String filename) throws IOException { Path externalTxtFile = Paths.get(filename).toAbsolutePath(); Path pathInZipfile = zipfs.getPath(filename.substring(filename.lastIndexOf("results"))); //all files to be stored have a common base folder, results/ in my case if (Files.isDirectory(externalTxtFile)) { Files.createDirectories(pathInZipfile); try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalTxtFile)) { for (Path child : ds) { addToZip(child.normalize().toString()); //recursive call } } } else { // copy file to zip file Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); } } 

下面的链接可以帮助: –

在Java中创buildZIP文件的函数