如何用Java压缩文件夹
时间:2020-01-09 10:35:31 来源:igfitidea点击:
在"如何用Java压缩文件"一文中,我们了解了如何用Java压缩单个文件或者多个文件,但是我们可能还需要用Java压缩文件夹,在压缩文件夹的同时还保留文件夹树结构。这篇文章展示了如何用Java压缩文件夹,其中zip归档文件包含整个树结构(文件和子目录)。
在Java中压缩文件夹的选项
为了压缩包含所有子文件夹和文件的文件夹,本文提供了两个选项。
- 使用Files.walkFileTree方法–使用此方法,我们可以递归访问文件树中的所有文件。 FileVisitor接口的实现提供给Files.walkFileTree方法,以访问文件树中的每个文件。 Java 7及更高版本提供此选项。参见示例。
- 通过使用java.io.File类中的listFiles()方法自己提供代码来递归读取文件夹中的文件。参见示例。
使用的目录结构
此处显示的用于压缩Java文件夹的Java程序使用以下目录结构。
在父文件夹中有一个子文件夹,子文件夹有两个文件,一个文件存储在父文件夹中。压缩档案应保留相同的树结构。
使用Files.walkFileTree方法在Java中压缩文件夹
此方法的参数之一是FileVisitor接口。我们确实需要根据需要提供此接口的实现。 FileVisitor界面有四种方法,要压缩文件夹,我们确实需要实现其中两种。
- preVisitDirectory –在访问目录条目之前调用。通过实现此方法,我们可以在zip存档中创建访问文件夹。
- visitFile –在要访问的文件上调用。通过实现此方法,我们可以将每个访问的文件添加到zip存档中。
import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.SimpleFileVisitor; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.zip.ZipOutputStream; import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; public class ZipFolder { public static void main(String[] args) { // Source folder final String SOURCE_DIR = "F:/theitroad/Parent"; // creating the name of the zipped archive String ZIP_DIR = SOURCE_DIR.concat(".zip"); zipFolderStructure(SOURCE_DIR, ZIP_DIR); } private static void zipFolderStructure(String sourceFolder, String zipFolder){ // Creating a ZipOutputStream by wrapping a FileOutputStream try (FileOutputStream fos = new FileOutputStream(zipFolder); ZipOutputStream zos = new ZipOutputStream(fos)) { Path sourcePath = Paths.get(sourceFolder); // Walk the tree structure using WalkFileTree method Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>(){ @Override // Before visiting the directory create the directory in zip archive public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException { // Don't create dir for root folder as it is already created with .zip name if(!sourcePath.equals(dir)){ System.out.println("Directory- " + dir); zos.putNextEntry(new ZipEntry(sourcePath.relativize(dir).toString() + "/")); zos.closeEntry(); } return FileVisitResult.CONTINUE; } @Override // For each visited file add it to zip entry public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { System.out.println("File Name- " + sourcePath.relativize(file).toString()); zos.putNextEntry(new ZipEntry(sourcePath.relativize(file).toString())); Files.copy(file, zos); zos.closeEntry(); return FileVisitResult.CONTINUE; }}); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
输出:
Directory- F:\theitroad\Parent\Child File Name- Child\hello.txt File Name- Child\Project.docx File Name- Test.txt
通过递归列出文件来压缩Java文件夹
在代码中,首先创建一个父文件夹中所有文件和文件夹的列表。为了在目录中使用文件列表,使用java.io.File类的listFiles()方法。
在列表中拥有此文件夹树结构后,便可以遍历该列表以创建zip存档。对于列表中的每个迭代元素,请检查它是目录还是文件
如果是目录,则只需在zip归档文件中添加目录的名称。
如果是文件,则添加名称以及文件内容。
public class ZippingFolder { List fileList = new ArrayList(); public static void main(String[] args) { // Source folder final String ROOT_DIR = "F:/theitroad/Parent"; // creating the name of the zipped archive String ZIP_DIR = ROOT_DIR.concat(".zip"); ZippingFolder zippingFolder = new ZippingFolder(); // get the list of the whole folder structure zippingFolder.getListOfFiles(new File(ROOT_DIR)); zippingFolder.zipTreeStructure(ROOT_DIR, ZIP_DIR); } private void zipTreeStructure(String ROOT_DIR, String zipDir){ final int BUFFER = 1024; BufferedInputStream bis = null; ZipOutputStream zos = null; try{ // Creating ZipOutputStream by wrapping FileOutputStream FileOutputStream fos = new FileOutputStream(zipDir); zos = new ZipOutputStream(fos); // iterating the folder tree structure for(File file : fileList){ // If directory if(file.isDirectory()){ // add the directory name as zipentry ZipEntry ze = new ZipEntry(file.getName()+"/"); zos.putNextEntry(ze); zos.closeEntry(); } // If file else{ FileInputStream fis = new FileInputStream(file); bis = new BufferedInputStream(fis, BUFFER); ZipEntry ze = new ZipEntry(getFileName(ROOT_DIR, file.toString())); zos.putNextEntry(ze); byte data[] = new byte[BUFFER]; int count; while((count = bis.read(data, 0, BUFFER)) != -1) { zos.write(data, 0, count); } bis.close(); zos.closeEntry(); } } }catch(IOException ioExp){ ioExp.printStackTrace(); } finally{ try { zos.close(); if(bis != null) bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // Method to get the folder tree structure private void getListOfFiles(File source){ File[] fileNames = source.listFiles(); for(File file : fileNames){ if(file.isDirectory()){ fileList.add(file); // recursive call to go through the subdirectory structure getListOfFiles(file); }else{ fileList.add(file); } } } // To get the relative file path private String getFileName(String ROOT_DIR, String filePath){ String name = filePath.substring(ROOT_DIR.length() + 1, filePath.length()); return name; } }