如何处理压缩文件
一、解压文件
1.后缀为.zip的文件
使用java.util.zip.ZipInputStream
类来解压.zip格式的压缩文件
使用ZipInputStream
的基本步骤:
- 创建一个
ZipInputStream
对象,然后传入FileInputStream
- 通过
getNextEntry
方法获取目录中的子文件(zipEntry
对象) - 获取到文件的路径,通过
mkdirs
和createNewFile
方法分别创建子目录与子文件 - 使用字节数组保存需要解压文件的字节,当读取的长度不为-1时,将对应字节数组写入文件
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file))) {
//遍历压缩包中每个子文件为一个zipEntry对象
ZipEntry zipEntry = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
System.out.println(zipEntry.getName());
//创建子目录或者子文件
File files = new File(rootDir.getPath() + "\\" + zipEntry.getName());
if (zipEntry.isDirectory()) {
//创建子目录
files.mkdirs();
} else {
//创建子文件
files.createNewFile();
try (FileOutputStream fileOutputStream = new FileOutputStream(files)) {
byte[] out = new byte[1024];
int len = -1;
while ((len = zipInputStream.read(out)) != -1) {
fileOutputStream.write(out, 0, len);
}
}
}
}
}
2.后缀为.rar的文件
使用com.github.junrar.Archive
来解压.rar
格式的文件
使用Archive
的基本步骤:
- 创建一个
Archive
对象,传入FileInputStream
- 使用
getFileHeaders()
方法获取文件对应的信息并保存到headers
列表中 - 对获取到的文件名称排序
- 获取到文件的路径,通过
mkdirs
和createNewFile
方法分别创建子目录与子文件 - 使用
org.apache.commons.io.FileUtils
的copyInputStreamToFile
方法将输入流复制到新的文件中
try(Archive archive = new Archive(new FileInputStream(path))){
List<FileHeader> headers = archive.getFileHeaders();
//按照名称排序
headers.sort(new Comparator<FileHeader>() {
@Override
public int compare(FileHeader o1, FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
for(FileHeader head: headers){
//创建子目录和子文件
File file = new File(fileDir.getPath() + "\\" + head.getFileName());
if(head.isDirectory()){
file.mkdirs();
}else {
file.createNewFile();
//获取压缩文件中的输入流
InputStream in = archive.getInputStream(head);
//将输入流复制到新的文件中
FileUtils.copyInputStreamToFile(in,file);
}
}
完整代码:
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.BaseBlock;
import com.github.junrar.rarfile.FileHeader;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Demo02 {
public static void main(String[] args) {
String path = "C:\\Users\\29136\\Desktop\\easyftp-server-1.7.0.10-cn.zip";
// String path = "C:\\Users\\29136\\Desktop\\实验案例.rar";
if (path.endsWith(".zip")) {
unzip(path);
} else if (path.endsWith(".rar")) {
unrar(path);
}
}
public static void unzip(String path) {
File file = new File(path);
//获取根目录
String sourse = file.getName();
File rootDir = new File(file.getParent() + "\\" + sourse.substring(0, sourse.lastIndexOf(".")));
//判断目录是否存在
if (rootDir.exists()) {
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//创建根目录
rootDir.mkdirs();
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file))) {
//遍历压缩包中每个子文件为一个zipEntry对象
ZipEntry zipEntry = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
System.out.println(zipEntry.getName());
//创建子目录或者子文件
File files = new File(rootDir.getPath() + "\\" + zipEntry.getName());
if (zipEntry.isDirectory()) {
//创建子目录
files.mkdirs();
} else {
//创建子文件
files.createNewFile();
try (FileOutputStream fileOutputStream = new FileOutputStream(files)) {
byte[] out = new byte[1024];
int len = -1;
while ((len = zipInputStream.read(out)) != -1) {
fileOutputStream.write(out, 0, len);
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void unrar(String path) {
//创建根目录
File rarFile = new File(path);
String sourse = rarFile.getName();
File fileDir = new File(rarFile.getParent() + "\\" + sourse.substring(0, sourse.lastIndexOf(".")));
if (fileDir.exists()){
try {
FileUtils.deleteDirectory(fileDir);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
fileDir.mkdirs();
try(Archive archive = new Archive(new FileInputStream(path))){
List<FileHeader> headers = archive.getFileHeaders();
//按照名称排序
headers.sort(new Comparator<FileHeader>() {
@Override
public int compare(FileHeader o1, FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
for(FileHeader head: headers){
//创建子目录和子文件
File file = new File(fileDir.getPath() + "\\" + head.getFileName());
if(head.isDirectory()){
file.mkdirs();
}else {
file.createNewFile();
//获取压缩文件中的输入流
InputStream in = archive.getInputStream(head);
//将输入流复制到新的文件中
FileUtils.copyInputStreamToFile(in,file);
}
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (RarException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
二、压缩文件
步骤:
- 通过调用
file.listFiles()
方法,获取目录下的所有文件并存储在File[] files
数组中 - 创建
ZipOutputStream
对象并指定输出流为将要创建的ZIP文件 out.putNextEntry(new ZipEntry(f.getName()))
来写入一个新的ZipEntry
对象,表示一个新的压缩文件条目。- 使用
Files.readAllBytes(f.toPath())
读取文件f
的所有字节内容,并通过out.write()
方法将字节内容写入 - 使用
out.closeEntry()
方法关闭Entry对象
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Demo05 {
public static void main(String[] args) {
File file = new File("D:\\素材\\视频\\Desktop\\c");
//获取原始文件
File[] files = file.listFiles();
try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file.getPath()+"\\"+file.getName()+".zip"))){
for(File f:files){
//写入zipEntry对象
out.putNextEntry(new ZipEntry(f.getName()));
//写入字节内容
out.write(Files.readAllBytes(f.toPath()));
//关闭Entry对象
out.closeEntry();
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}