java 文件压缩 解压_Java文件压缩与解压缩(一)
package com.cn;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
//錯(cuò)誤小結(jié):
//1 關(guān)于file.isFile()與file.isDirectory()記憶出了偏差.
// 錯(cuò)誤以為若是Directory一定是file,file不一定是Directory
// 更正:file和Directory是兩碼事.只能是file或Directory中其中一個(gè).
//2 并不是說我們執(zhí)行一句File f=new File("F:\\x.txt");
// 在本地硬盤上就生成了一個(gè)x.txt文件.而應(yīng)該進(jìn)行如下的
// 操作才可以.
// File f=new File("F:\\x.txt");
// if (!f.exists()) {
// f.createNewFile();
// }
// 其中f.createNewFile()表示創(chuàng)建了一個(gè)空文件
//
// 多數(shù)的情況下,我們執(zhí)行了File f=new File("F:\\x.txt")
// 以后再利用輸入流,輸出流對(duì)f進(jìn)行操作,比如往該x.txt文件中
// 寫入hello world
//
//3 血的教訓(xùn):
// zip()方法中沒有關(guān)閉流zos.導(dǎo)致壓縮后的文件解壓時(shí)出錯(cuò)
//重要總結(jié):
//1 關(guān)于zip和unzip的核心操作對(duì)象是每一個(gè)文件!!!
// 比如碰到一個(gè)directory,那么會(huì)去遍歷里面的每一個(gè)文件,挨個(gè)對(duì)其進(jìn)行壓縮.
// 不要錯(cuò)誤地理解,若是一個(gè)directory,那么會(huì)將其作為一個(gè)整體進(jìn)行壓縮.
//2 在JAVA中每一個(gè)壓縮文件都用一個(gè)ZipEntry表示
// 所以在壓縮的過程中要得到每個(gè)文件的完整路徑(從最外層文件夾至文件本身)
// 用此完整路徑為每個(gè)壓縮文件new()一個(gè)ZipEntry
//3 所以利用zipEntry可記錄原來的目錄層次.解壓后才保持原樣
// 也可以看到在解壓時(shí)利用entrys.hasMoreElements()來挨個(gè)
// 解壓每個(gè)zipEntry.
// 參見解壓中的代碼:
// perUnzipFilePath = unzipPath + zipEntry.getName();
public class TestZipAndUnZip {
public static void main(String[] args) throws Exception {
TestZipAndUnZip test=new TestZipAndUnZip();
//壓縮和解壓?jiǎn)蝹€(gè)文件
test.zip2("F:\\kk\\cc.txt","F:\\11.zip");
test.unZipFile2("F:\\11.zip", "F:\\test11");
//壓縮和解壓一個(gè)目錄
test.zip2("F:\\kk","F:\\22.zip");
test.unZipFile2("F:\\22.zip", "F:\\test22");
}
/**
* 該方法將一個(gè)給定路徑的文件壓縮
* @param willZipPath 待壓縮文件的路徑
* @param zipedPath 該文件壓縮后的路徑
*/
public void zip2(String willZipPath, String zipedPath) {
try {
File willZipFile = new File(willZipPath);
File zipedFile = new File(zipedPath);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipedFile));
if (willZipFile.isFile()) {
fileToZip2(willZipPath, zos);
}
if (willZipFile.isDirectory()) {
dirToZip2(willZipPath, willZipFile, zos);
}
// 方法調(diào)用完成后關(guān)閉流
zos.close();
} catch (Exception e) {
}
}
/**
* @param willZipFilePath 待壓縮文件的路徑
* @param zos 壓縮文件輸出流
* 1 關(guān)于以下兩句代碼
* ZipEntry entry = new ZipEntry();
* zos.putNextEntry(entry);
* 把生成的ZipEntry對(duì)象加入到壓縮文件中
* 之后往壓縮文件中寫入的內(nèi)容均放在該ZipEntry對(duì)象中
*
* 2 fis.close()但是不能在此處zos.close()
* 因?yàn)樵搝os是上一方法傳遞過來的.可能在壓縮目錄的時(shí)候會(huì)
* 再次使用到該zos流.若此時(shí)關(guān)閉,則導(dǎo)致目錄中的一個(gè)文件
* 被壓縮
*/
public void fileToZip2(String willZipFilePath,ZipOutputStream zos){
try {
File willZipFile=new File(willZipFilePath);
ZipEntry entry = new ZipEntry(getEntryName2(willZipFilePath, willZipFile));
zos.putNextEntry(entry);
FileInputStream fis = new FileInputStream(willZipFilePath);
int len = 0;
while ((len = fis.read()) != -1){
zos.write(len);
}
fis.close();
//流關(guān)閉錯(cuò)誤!
//zos.close();
} catch (Exception e) {
}
}
/**
* @param willZipDirctoryPath 原目錄所在路徑
* @param willZipedDirectory 原目錄
* @param zos 壓縮流
* 注意:
* 在處理空文件夾的時(shí)候
* getEntryName2(willZipDirctoryPath, willZipedDirectory)+"/"
* 中的"/"是必不可少的
*/
public void dirToZip2(String willZipDirctoryPath,File willZipedDirectory, ZipOutputStream zos) {
if (willZipedDirectory.isDirectory()) {
File[] files = willZipedDirectory.listFiles();
//處理空文件夾的情況
if (files.length==0) {
ZipEntry zipEntry=new ZipEntry
(getEntryName2(willZipDirctoryPath, willZipedDirectory)+"/");
try {
zos.putNextEntry(zipEntry);
} catch (Exception e) {
e.printStackTrace();
}
return;
}
for (int i = 0; i < files.length; i++) {
File file = files[i];
//若是文件,遞歸調(diào)用fileToZip()
if (file.isFile()) {
fileToZip2(file.getAbsolutePath(), zos);
}
//若是文件,遞歸調(diào)用dirToZip()
if (file.isDirectory()) {
dirToZip2(file.getAbsolutePath(),file, zos);
}
}
}
}
/**
* @param rawPath 需要壓縮的目錄或者文件的完整路徑
* @param file 需要壓縮的文件或者目錄
* @return entryName
*
* 該方法返回EntryName,表示從最外層目錄開始到該文件(目錄)
* 的完整路徑
* 備注:
* 1 該示例中文件均存放在某盤下,如E:\所以rawPath.substring(3);
* 2 注釋中"@param file 需要壓縮的文件或者目錄".其實(shí)絕大多數(shù)情況下
* 都是文件,只有一種情況是目錄,就是空文件夾的情況.
*/
public String getEntryName2(String rawPath,File file){
try {
String rawDir=rawPath.substring(3);
int rawDirIndex=file.getAbsolutePath().indexOf(rawDir);
String entryName=file.getAbsolutePath().substring(rawDirIndex);
return entryName;
} catch (Exception e) {
}
return null;
}
/**
* @param zipedFilePath 原壓縮文件的路徑
* @param unzipPath 文件解壓后的路徑
* 對(duì)于文件或者目錄操作的小梳理:
* 1 對(duì)于目錄應(yīng)該先執(zhí)行file.mkdir(s)()才可以
* 往里面其下存入文件.比如:
* File f=new File("F:\\test\\x.txt");
if (!f.exists()) {
f.createNewFile();
}
這當(dāng)然要報(bào)錯(cuò),因?yàn)閤.txt的所在目錄還不存在!!
所以應(yīng)該改正為:
File f=new File("F:\\test\\x.txt");
f.getParentFile().mkdirs();
if (!f.exists()) {
f.createNewFile();
}
2同樣的道理
File f=new File("F:\\test\\x.txt");
if (f.isFile()) {
System.out.println("true");
}else{
System.out.println("false");
}
結(jié)果為false
3類似的問題
File f=new File("F:\\x.txt");
if (f.isFile()) {
System.out.println("true");
}else{
System.out.println("false");
}
結(jié)果為false
因?yàn)橹皇莕ew了一個(gè)File,并沒有創(chuàng)建!!!
File f=new File("F:\\x.txt");
f.createNewFile();
if (f.isFile()) {
System.out.println("true");
}else{
System.out.println("false");
}
此時(shí)為true
此處:
if (zipEntry.isDirectory()) {
new File(perUnzipFilePath).mkdirs();
} else {
new File(perUnzipFilePath).getParentFile().mkdirs();
}
已經(jīng)建立了每個(gè)文件夾.
然后才開始對(duì)每個(gè)空文件夾和每個(gè)文件進(jìn)行流操作.
和上面的道理一致,剛開始犯了個(gè)錯(cuò)誤,沒有采用
else {
fos = new FileOutputStream(perUnzipFile);
is = zipFile.getInputStream(zipEntry);
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
而是用if(perUnzipFile.isFile()){}來操作,這當(dāng)然錯(cuò)了.
因?yàn)樵損erUnzipFile沒有執(zhí)行perUnzipFile.createNewFile();
所以它還不是File.類似的情況,多采用流操作來進(jìn)行讀寫.
所以總結(jié)兩種與File有關(guān)的操作:
1 File f=new File("");
f.createNewFile();
然后對(duì)f操作
2 file f=new File("");
然后用輸入輸出流進(jìn)行流操作
舉例子:
File f=new File("F:\\2221x.txt");
FileOutputStream fos=new FileOutputStream(f);
String string="hello";
byte []b=string.getBytes();
fos.write(b, 0, b.length);
該例子是正確的.
疑問:沒有執(zhí)行 f.createNewFile()為什么不報(bào)錯(cuò).因?yàn)檩敵隽?/p>
FileOutputStream已經(jīng)幫我們做了該工作了.
修改例子即可知:
File f=new File("F:\\2221x.txt");
if (f.isFile()) {
System.out.println("true1");
} else {
System.out.println("false1");
}
FileOutputStream fos=new FileOutputStream(f);
if (f.isFile()) {
System.out.println("true2");
} else {
System.out.println("false2");
}
String string="hello";
byte []b=string.getBytes();
fos.write(b, 0, b.length);
輸出false1,true2
這就得到了驗(yàn)證.
*/
public void unZipFile2(String zipedFilePath, String unzipPath) {
FileOutputStream fos=null;
InputStream is=null;
ZipEntry zipEntry=null;
String perUnzipFilePath=null;
if (!unzipPath.endsWith(File.separator)) {
unzipPath+=File.separator;
}
try {
ZipFile zipFile=new ZipFile(zipedFilePath);
Enumeration entries=zipFile.entries();
byte [] buffer=new byte[1024*8];
int len=0;
while (entries.hasMoreElements()) {
zipEntry = (ZipEntry) entries.nextElement();
perUnzipFilePath = unzipPath + zipEntry.getName();
//1建立每個(gè)文件夾
if (zipEntry.isDirectory()) {
//處理空文件夾的情況
//創(chuàng)建空目錄
new File(perUnzipFilePath).mkdirs();
} else {
//為每個(gè)文件創(chuàng)立其所在目錄
new File(perUnzipFilePath).getParentFile().mkdirs();
}
//2在用流操作處理每個(gè)文件夾中的文件
// 2.1if中的操作只是針對(duì)空目錄而進(jìn)行的.所以if中的代碼可以
// 注釋掉,無實(shí)際意義.
// 2.2else中的操作是對(duì)于每個(gè)具體的文件而進(jìn)行的流操作
File perUnzipFile = new File(perUnzipFilePath);
if (perUnzipFile.isDirectory()) {
File[] files = perUnzipFile.listFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
fos = new FileOutputStream(file);
is = zipFile.getInputStream(zipEntry);
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
} else {
fos = new FileOutputStream(perUnzipFile);
is = zipFile.getInputStream(zipEntry);
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
}
if (fos!=null) {
fos.close();
}
if (is!=null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ps:
Java文件壓縮與解壓縮(一),最好.
Java文件壓縮與解壓縮(三),其次.
總結(jié)
以上是生活随笔為你收集整理的java 文件压缩 解压_Java文件压缩与解压缩(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《强酒》是哪个时期的作品?
- 下一篇: 做唐氏筛查多少钱啊?