如何用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;
}
}

