字节流
InputStream 解压缩流 --输入流
OutputStream 压缩流 --输出流
本质: 压缩包里面的每一个文件都是ZipEntry对象,所以解压的本质就是按照层级的顺序把每一个ZipEntry对象拷贝到本地的另一个文件夹中
public class Demo01 {
/**
* 解压缩 -- Java只能识别zip压缩包
*/
//压缩包路径
private static final String ZIP_PATH = "/Users/chenjp/tmp/stream.zip";
//解压目的地
private static final String UNZIP_PATH = "/Users/chenjp/tmp/unzip/";
public static void main(String[] args) throws IOException{
//创建一个File表示要解压的压缩包
File src = new File(ZIP_PATH);
//创建一个File表示解压的目的地
File dest = new File(UNZIP_PATH);
dest.mkdirs();
//解压缩
unzip(src,dest);
}
/**
* “macosx”是“MetaData”产生的文件夹;
* 在Mac系统上压缩出来的文件,会自动将一些缓存的内容一起压缩 ,
* 而这些是在Mac系统中不可见的,只有在Windows系统解压后才能看到,
* 所以在Windows里 “__MACOSX” 就成了垃圾文件。首先我们得知道,
* 这个世界上除了Windows操作系统之外,还有一些其他的操作系统,
* 比如Linux,比如苹果家电脑使用的Mac OS,而当你在Mac OS X系统中对文件进行压缩之后(*.zip),
* 便会在压缩包中生成这些_macosx的文件。x这个字母在罗马文之中是十的意思,
* 而macosx则正是mac os系统的第十个版本,
* 想来看到这里大家都明白了吧。由于是在Mac系统上压缩出来的文件,
* 会自动将一些缓存的内容一起压缩 ,而这些是在Mac系统中不可见的。
* 只有在Windows系统解压后才能看到。在Windows里 “__MACOSX”
* 就成了垃圾文件。所以这个文件在Windows操作系统中不用去管他就行了,删除也可以。
*/
//定义一个方法来解压压缩包
public static void unzip(File src, File dest) throws IOException {
//解压的本质就是按照层级的顺序把每一个ZipEntry对象拷贝到本地
//创建一个解压缩流来读取压缩包中的数据
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(src));
//要先获取到压缩包里面的每一个zipEntry对象
// ZipEntry entry = zipInputStream.getNextEntry(); //当压缩包中读取完数据后会返回null
//表示当前在压缩包中获取到的文件夹或者文件
ZipEntry entry;
while ( (entry = zipInputStream.getNextEntry() ) != null){
System.out.println(entry);
if (entry.toString().contains("__MACOSX") || ("\\.".equals(entry.toString().substring(0,1))) ){
zipInputStream.closeEntry();
continue;
}
if (entry.isDirectory()){
//文件夹:需要在目的地dest处创建一个同样的文件夹
File file = new File(dest, entry.toString());
file.mkdirs();
}else {
//文件:需要读取到压缩包中的文件,并把他存放到目的地的dest文件夹中(按照层级目录进行存放)
File file = new File(dest, entry.toString());
File fileParent = new File(file.getParent());
if (!fileParent.exists()){
fileParent.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
int b ;
while ( (b = zipInputStream.read()) != -1 ){
//写到目的地
fos.write(b);
}
fos.close();
zipInputStream.closeEntry();//表示在压缩包中的一个文件处理完毕了
}
}
zipInputStream.close();
}
}
压缩的本质:压缩包里面的每一个文件或者文件夹都是ZipEntry对象,本质还是把每一个(文件/文件夹)看成ZipEntry对象放到压缩包中
public class Demo02 {
public static final String FILE_PATH = "/Users/chenjp/tmp/stream/c.txt";//a.jpg
public static final String ZIP_PATH = "/Users/chenjp/tmp/";
public static void main(String[] args) throws IOException {
//创建File对象表示要压缩的文件
File srcFile = new File(FILE_PATH);
//创建File对象表示压缩包的位置
File dest = new File(ZIP_PATH);
//调用压缩的方法
zipFile(srcFile, dest);
}
/**
* 压缩单个文件
* src 要压缩的文件
* dest 压缩包的位置
*/
public static void zipFile(File src,File dest) throws IOException{
String zipname = src.getName().split("\\.")[0]+".zip";
System.out.println(zipname);
//创建压缩流关联压缩包
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(new File(dest,zipname)));
//创建zipEntry对象,表示压缩包里的每一个文件/文件夹
ZipEntry entry = new ZipEntry(src.getName());
//把ZipEntry对象放到压缩包当中
zipOutputStream.putNextEntry(entry);
//把src文件中的数据写到压缩包中
FileInputStream fis = new FileInputStream(src);
int b ;
while( (b = fis.read( ) ) != -1){
zipOutputStream.write(b);
}
zipOutputStream.closeEntry();
zipOutputStream.close();
}
}
public class Demo03 {
public static final String DIR_PATH = "/Users/chenjp/tmp/stream";
public static final String ZIP_PATH = "/Users/chenjp/tmp/";
public static void main(String[] args) throws IOException {
//创建File对象表示需要压缩的文件夹位置
File src = new File(DIR_PATH);
//创建File对象表示压缩包的存放位置(压缩包的父级路径)
File destParent = new File(ZIP_PATH);
//压缩包的全路径
File dest = new File(destParent, src.getName() + ".zip");
System.out.println(dest.getPath());
//创建压缩流关联压缩包
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(dest));
//获取src里面的每一个文件,变成ZipEntry对象,放到压缩包中
zipDir(src,zipOutputStream,src.getName());
//释放资源
zipOutputStream.close();
}
/**
* 压缩文件夹
* 参数一:数据源
* 参数二:压缩流
* 参数三:压缩包内部的路径
*/
public static void zipDir(File src ,ZipOutputStream zipOutputStream,String name) throws IOException{
System.out.println(name);//这里面的name可以理解为压缩包中的文件父级目录路径
//进入src文件夹
File[] files = src.listFiles();
//遍历数组
for (File file : files) {
if (file.isFile()){
//判断-文件 ,变成ZipEntry对象,放到压缩包中
ZipEntry entry = new ZipEntry(name + "/" + file.getName());
zipOutputStream.putNextEntry(entry);
//读取文件
FileInputStream fis = new FileInputStream(file);
int b ;
while ( (b = fis.read() ) != -1){
zipOutputStream.write(b);
}
fis.close();
zipOutputStream.closeEntry();
}else {
//判断是文件夹,递归
String path = name + "/" +file.getName();
zipDir(file,zipOutputStream,path);
}
}
}
}