压缩文件大致分为两种:zip格式的压缩文件或者是rar格式的压缩文件;
zip压缩文件的读取
在进行zip压缩文件的读取时(解压到当前目录的同名目录下),我们需要引入ZipInputStream来进行zip格式的压缩文件输入流来进行文件的读取。
按照以下步骤进行zip文件的解压缩:
(1)我们要传入需要解压缩的zip文件的路径并创建源文件的File对象;
(2)获取到根目录的路径名称(最后一个.的位置之前),并保存为一个新的File对象;
(3)判断当前根目录下是否存在此需要创建的目录,如果存在需要使用commens-io包提供的FileUtils工具类来进行根目录的删除;
(4)当前目录下不存在需要创建的目录,创建同名目录;
(5)使用zipInputStream作为zip压缩文件输入流,并传入FileInputStream对象来读取zip压缩文件中的所有子目录或者子文件(每个子文件或者子目录都是一个zipEntry类型的对象);
(6)循环调用getNextStream(),当返回值为null是循环结束, getNextStream()方法的返回值类型为zipEntry,作用是为了获取压缩文件的每个子文件,要想获取压缩文件的内容,就需要调用read() 进行不断的读取,直到返回-1.
//解压缩zip格式的文件
public static void unzip(String path) {
//根据原始路径,创建源文件的(File对象)
File soueceFile=new File(path);
//根目录
String filename=soueceFile.getName();
File rootFile=new File(soueceFile.getParent()+"\\"+filename.substring(0,filename.lastIndexOf(".")));
//判断根目录是否存在
if (rootFile.exists()) {
//rootFile.delete();//仅能删除空目录
//使用commens-io包提供的FileUtils工具类来进行根目录的删除
try {
FileUtils.deleteDirectory(rootFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//创建根目录
rootFile.mkdir();
//zipinputstream:用于进行zip格式的压缩文件输入流
try(ZipInputStream zipInputStream=new ZipInputStream(new FileInputStream(soueceFile));) {
//遍历每个压缩包中的每个子文件或者子目录(zipEntry类型的对象)
ZipEntry zipEntry=null;
while((zipEntry=zipInputStream.getNextEntry())!=null) {
//创建子目录过着子文件
File file =new File(rootFile.getPath()+"\\"+zipEntry.getName());
if (zipEntry.isDirectory()) {
//物理磁盘创建子目录
file.mkdir();
}else {
//物理磁盘创建子文件
file.createNewFile();
//读取当前压缩包中的子文件并通过输出流写入
try(FileOutputStream outputStream=new FileOutputStream(file);){
byte[] buff =new byte[1024];
int len=-1;
while ((len=zipInputStream.read(buff))!=-1) {
outputStream.write(buff,0,len);
}
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
rar压缩文件的读取
在进行rar压缩文件的读取时(解压到当前目录的同名目录下),我们需要引入第三方库junrar来进行rar格式的压缩文件的读取。
通过以下步骤进行rar压缩文件的解压缩:
1)我们要传入需要解压缩的zip文件的路径并创建源文件的File对象;
(2)获取到根目录的路径名称(最后一个.的位置之前),并保存为一个新的File对象;
(3)判断当前根目录下是否存在此需要创建的目录,如果存在需要使用commens-io包提供的FileUtils工具类来进行根目录的删除;
(4)当前目录下不存在需要创建的目录,创建同名目录;
(5)通过使用junrar第三方库的Archive对象,用于rar压缩文件的读取。获取到的每个子目录或者子文件都是一个FileHeader对象,并且是深层遍历每个子目录并放到list集合中。
(6)为了获取到正确的目录需要使用sort方法对list集合进行排序;
(7)循环调用getNextStream(),当返回值为null是循环结束, getNextStream()方法的返回值类型为zipEntry,作用是为了获取压缩文件的每个子文件,要想获取压缩文件的内容,就需要调用read() 进行不断的读取,直到返回-1.
//解压rar格式的压缩文件
public static void unrar(String path) {
//创建解压缩的原始根目录
File rarFile=new File(path);
File rootDir=new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
if (rootDir.exists()) {
try {
FileUtils.deleteDirectory(rootDir);
} catch (Exception e) {
// TODO: handle exception
}
}
rootDir.mkdir();
//创建Archive对象,用于读取rar压缩文件
try(Archive archive=new Archive(new FileInputStream(path));){
//获取压缩文件中的所有子目录或者子文件(FileHeader对象)
List<FileHeader> fileHeaders=archive.getFileHeaders();
//按照子目录或者子文件的名称排序
fileHeaders.sort(new Comparator<FileHeader>() {
@Override
public int compare(FileHeader o1, FileHeader o2) {
// TODO Auto-generated method stub
return o1.getFileName().compareTo(o2.getFileName());
}
});
//遍历压缩文件中的所有子文件子目录
for (FileHeader fileHeader : fileHeaders) {
File file=new File(rootDir.getPath()+"\\"+fileHeader.getFileName());
//如果是子目录创建子目录,如果是子文件则创建子文件
if (fileHeader.isDirectory()) {
//创建子目录
file.mkdir();
} else {
//创建子文件
file.createNewFile();
//获取压缩文件中的子文件输入流
InputStream inputStream=archive.getInputStream(fileHeader);
//复制文件输入流至新的子文件
FileUtils.copyInputStreamToFile(inputStream, file);
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RarException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}