Java的檔案操作--2(Zip檔案釋放)

來源:互聯網
上載者:User

  在java中專門有一個對zip檔案操作的包(java.util.zip),對zip檔案操作挺方便的,上次說寫一個zip檔案釋放程式,花了一天時間終於寫完了,起先想起來挺簡單的:原理就是將zip檔案中的檔案夾和檔案通過ZipInputStream和ZipEntry類一一得出,然後分別再對應目錄下建立檔案和檔案夾。可是實現起來就不是那麼回事了,其中有好多細節問題都不好解決,其中在調用ZipInputStream中的getNextEntry方法時如果zip檔案中包含中文路徑名或者檔案名稱就會拋出異常,所以這段程式難免會有許多錯誤和bug,甚至還有些思路上的問題,希望大家能多提意見。
     其實java中對檔案的操作就是對輸入輸出資料流的運用和控制,這樣講有些範,但是如果你理解了流的運用就會覺得對檔案操作原來就是這樣呀!但是你千萬不要以為java的輸入輸出就這麼簡單,會用和用的好是兩碼事,就象同樣形容思想堅決,果斷和武斷就是兩個截然不同的描述,因此要想用好java的出入輸出還需要多多練習,多多思考。好了,說了那麼多都是些廢話,下面是程式源碼,希望對大家有用!
                                                      pcera
                                                      2005-7-2   17:44

/**
 *類名:zipFileRelease
 *說明:對zip檔案解壓,釋放在指定,目錄下
 *介紹:主要的zip檔案釋放方法releaseHandle()
 *  用ZipInputStream類和ZipEntry類將zip檔案的入口清單列舉出來,然後
 *  根據使用者提供的輸出路徑和zip檔案的入口進行組合通過DataOutputStream
 *  和File類進行檔案的建立和目錄的建立,建立檔案時的檔案資料是通過
 *  ZipInputStream類、ZipEntry類、InputStream類之間的套嵌組合獲得的。
 *注意:如果zip檔案中包含中文路徑程式將會拋出異常
 *日期:2005-7-1
 *作者:Pcera
 */

import java.io.*;
import java.util.*;
import java.util.zip.*;

class zipFileRelease{

 private String inFilePath;
 private String releaseFilePath;
 private String[] FileNameArray;      //存放檔案名稱的數組
 private ZipEntry entry;
 //
 private FileInputStream fileDataIn;
 private FileOutputStream fileDataOut;
 private ZipInputStream zipInFile;
 private DataOutputStream writeData;
 private DataInputStream readData;
 //
 private int zipFileCount = 0;        //zip檔案中的檔案總數
 private int zipPathCount = 0;        //zip檔案中的路徑總數

 /**
  *初始化函數
  *初始化zip檔案流、輸出檔案流以及其他變數的初始化
  */
 public zipFileRelease(String inpath,String releasepath){
  inFilePath = inpath;
  releaseFilePath = releasepath;
 }

 /**
  *初始化讀取檔案流函數
  *參數:FileInputStream類
  *傳回值:初始化成功返回0,否則返回-1
  */
 protected long initInStream(ZipInputStream zipFileA){
  try{
   readData = new DataInputStream(zipFileA);
   return 0;
  }catch(Exception e){
   e.printStackTrace();
   return -1;
  }
 }

 /**
  *測試檔案路徑
  *參數:zip檔案的路徑和要釋放的位置
  *傳回值:是兩位整數,兩位元中的十位代表輸入路徑和輸出路徑(1輸入、2輸出)
  *  各位元是代表絕對路徑還是相對路徑(1絕對、0相對)
  *  返回-1表示路徑無效

 protected long checkPath(String inPath,String outPath){
  File infile = new File(inPath);
  File infile = new File(outPath);

 }
 */

 /**
  *初始化輸出檔案流
  *參數:File類
  *傳回值:初始化成功返回0,否則返回-1
  */
 protected long initOutStream(String outFileA){
  try{
   fileDataOut = new FileOutputStream(outFileA);
   writeData = new DataOutputStream(fileDataOut);
   return 0;
  }catch(IOException e){
   e.printStackTrace();
   return -1;
  }
 }

 /**
  *測試檔案是否存在方法
  *參數:File類
  *傳回值:如果檔案存在返迴文件大小,否則返回-1
  */
 public long checkFile(File inFileA){
  if (inFileA.exists()){
   return 0;
  }else{
   return -1;
  }
 }

 /**
  *判斷檔案是否可以讀取方法
  *參數:File類
  *傳回值:如果可以讀取返回0,否則返回-1
  */
 public long checkOpen(File inFileA){
  if(inFileA.canRead()){
   return inFileA.length();
  }else{
   return -1;
  }
 }

 /**
  *獲得zip檔案中的檔案夾和檔案總數
  *參數:File類
  *傳回值:如果正常獲得則返回總數,否則返回-1
  */
 public long getFilFoldCount(String infileA){
  try{
   int fileCount = 0;
   zipInFile = new ZipInputStream(
      new FileInputStream(infileA));
   while ((entry = zipInFile.getNextEntry()) != null){
    if (entry.isDirectory()){
     zipPathCount++;
    }else{
     zipFileCount++;
    }
    fileCount++;
   }
   return fileCount;
  }catch(IOException e){
   e.printStackTrace();
   return -1;
  }
 }

 /**
  *讀取zip檔案清單函數
  *參數:File類
  *傳回值:檔案清單數組
  */
 public String[] getFileList(String infileA){
  try{
   ZipInputStream AzipInFile = new ZipInputStream(
      new FileInputStream(infileA));
   //建立數組對象
   FileNameArray = new String[(int)getFilFoldCount(infileA)];

   //將檔案名稱清單傳入數組
   int i = 0;
   while ((entry = AzipInFile.getNextEntry()) != null){
    FileNameArray[i++] = entry.getName();
   }
   return FileNameArray;
  }catch(IOException e){
   e.printStackTrace();
   return null;
  }
 }

 /**
  *建立檔案函數
  *參數:File類
  *傳回值:如果建立成功返回0,否則返回-1
  */
 public long writeFile(String outFileA,byte[] dataByte){
  try{
   if (initOutStream(outFileA) == 0){
    writeData.write(dataByte);
    fileDataOut.close();
    return 0;
   }else{
    fileDataOut.close();
    return -1;
   }
  }catch(IOException e){
   e.printStackTrace();
   return -1;
  }
 }

 /**
  *讀取檔案內容函數
  *參數:File類
  *傳回值:如果讀取成功則返回讀取資料的位元組數組,如果失敗則返回空值
  */
 protected byte[]
 readFile(ZipEntry entryA,ZipInputStream zipFileA){
  try{
   long entryFilelen;
   if (initInStream(zipFileA) == 0){
    if ((entryFilelen = entryA.getSize()) >= 0){
     byte[] entryFileData = new byte[(int)entryFilelen];
     readData.readFully(entryFileData,0,(int)entryFilelen);
     return entryFileData;
    }else{
     return null;
    }
   }else{
    return null;
   }
  }catch(IOException e){
   e.printStackTrace();
   return null;
  }
 }

 /**
  *建立目錄函式
  *參數:要建立目錄的路徑
  *傳回值:如果建立成功則返回0,否則返回-1
  */
 public long createFolder(String dir){
  File file = new File(dir);
  if (file.mkdirs()) {
   return 0;
  }else{
   return -1;
  }
 }

 /**
  *刪除檔案
  *參數:要刪除的檔案
  *傳回值:如果刪除成功則返回0,要刪除的檔案不存在返回-2
  *  如果要刪除的是個路徑則返回-3,刪除失敗則返回-1
  */
 public long deleteFile(String Apath) throws SecurityException {
  File file = new File(Apath.trim());
  //檔案或路徑不存在
  if (!file.exists()){
   return -2;
  }
  //要刪除的是個路徑
  if (!file.isFile()){
   return -3;
  }
  //刪除
  if (file.delete()){
   return 0;
  }else{
   return -1;
  }
 }

 /**
  *刪除目錄
  *參數:要刪除的目錄
  *傳回值:如果刪除成功則返回0,刪除失敗則返回-1
  */
 public long deleteFolder(String Apath){
  File file = new File(Apath);
  //刪除
  if (file.delete()){
   return 0;
  }else{
   return -1;
  }
 }

 /**
  *判斷所要解壓的路徑是否存在同名檔案
  *參數:解壓路徑
  *傳回值:如果存在同名檔案返回-1,否則返回0
  */
 public long checkPathExists(String AreleasePath){
  File file = new File(AreleasePath);
  if (!file.exists()){
   return 0;
  }else{
   return -1;
  }
 }

 /**
  *刪除zip中的檔案
  *參數:檔案清單數組,釋放路徑
  *傳回值:如果刪除成功返回0,否則返回-1
  */
 protected
 long deleteReleaseZipFile(String[] listFilePath,String releasePath){
  long  arrayLen,flagReturn;
  int k = 0;
  String tempPath;
  //存放zip檔案清單的路徑
  String[] pathArray = new String[zipPathCount];
  //刪除檔案
  arrayLen = listFilePath.length;
  for(int i=0;i<(int)arrayLen;i++){
   tempPath = releasePath.replace('\\','/') + listFilePath[i];
   flagReturn = deleteFile(tempPath);
   if (flagReturn == -2){
    //什麼都不作
   }else if (flagReturn == -3){
    pathArray[k++] = tempPath;
   }else if (flagReturn == -1){
    return -1;
   }
  }
  //刪除路徑
  for(k = k - 1;k>=0;k--){
   flagReturn = deleteFolder(pathArray[k]);
   if (flagReturn == -1) return -1;
  }
  return 0;
 }

 /**
  *獲得zip檔案的最上層的檔案夾名稱
  *參數:zip檔案路徑
  *傳回值:檔案夾名稱,如果失敗則返回null
  */
 public String getZipRoot(String infileA){
  String rootName;
  try{
   FileInputStream tempfile = new FileInputStream(infileA);
   ZipInputStream AzipInFile = new ZipInputStream(tempfile);
   ZipEntry Aentry;
   Aentry = AzipInFile.getNextEntry();
   rootName = Aentry.getName();
   tempfile.close();
   AzipInFile.close();
   return rootName;
  }catch(IOException e){
   e.printStackTrace();
   return null;
  }
 }

 /**
  *釋放流,釋放佔用資源
  */
 protected void closeStream() throws Exception{
  fileDataIn.close();
  fileDataOut.close();
  zipInFile.close();
  writeData.flush();
 }

 /**
  *解壓函數
  *對使用者的zip檔案路徑和解壓路徑進行判斷,是否存在和開啟
  *在輸入解壓路徑時如果輸入"/"則在和zip檔案存放的統計目錄下進行解壓
  *傳回值:0表示釋放成功
  *  -1 表示您所要解壓的檔案不存在、
  *  -2表示您所要解壓的檔案不能被開啟、
  *  -3您所要釋放的路徑不存在、
  *  -4您所建立檔案目錄失敗、
  *  -5寫入檔案失敗、
  *  -6表示所要釋放的檔案已經存在、
  *  -50表示檔案讀取異常
  */
 public long releaseHandle() throws Exception{
  File inFile = new File(inFilePath);
  File outFile = new File(releaseFilePath);
  String tempFile;
  String zipPath;
  String zipRootPath;
  String  tempPathParent;   //存放釋放路徑
  byte[] zipEntryFileData;

  //作有效性判斷
  if (checkFile(inFile) == -1) {
   return -1;}
  if (checkOpen(inFile) == -1) {
   return -2;}
  //不是解壓再目前的目錄下時對路徑作有效性檢驗
  if (!releaseFilePath.equals("/")){
   //解壓在使用者指定目錄下
   if (checkFile(outFile) == -1) {
    return -3;}
  }
  //獲得標準釋放路徑
  if (!releaseFilePath.equals("/")) {
   tempPathParent = releaseFilePath.replace('\\','/')+ "/";
  }else{
   tempPathParent = inFile.getParent().replace('\\','/')+ "/";
  }
  //獲得zip檔案中的入口清單
  FileNameArray = getFileList(inFilePath);
  //獲得zip檔案的最上層目錄
  zipRootPath = getZipRoot(inFilePath);
  //
  fileDataIn = new FileInputStream(inFilePath);
  zipInFile = new ZipInputStream(fileDataIn);
  //判斷是否已經存在要釋放的檔案夾
  if (checkPathExists(tempPathParent +
    zipRootPath.substring(0,zipRootPath.lastIndexOf("/"))) == -1){
     return -6;
  }
  //
  try{
  //建立檔案夾和檔案
  int i = 0;
  while ((entry = zipInFile.getNextEntry()) != null){
   if (entry.isDirectory()){
    //建立目錄
    zipPath = tempPathParent + FileNameArray[i];
    zipPath = zipPath.substring(0,zipPath.lastIndexOf("/"));
    if (createFolder(zipPath) == -1){
     closeStream();
     deleteReleaseZipFile(FileNameArray,tempPathParent);
     return -4;
    }

   }else{
    //讀取檔案資料
    zipEntryFileData = readFile(entry,zipInFile);
    //向檔案寫資料
    tempFile = tempPathParent + FileNameArray[i];
    //寫入檔案
    if (writeFile(tempFile,zipEntryFileData) == -1){
     closeStream();
     deleteReleaseZipFile(FileNameArray,tempPathParent);
     return -5;
    }
   }
   i++;
  }
  //釋放資源
  closeStream();
  return 0;
  }catch(Exception e){
   closeStream();
   deleteReleaseZipFile(FileNameArray,tempPathParent);
   e.printStackTrace();
   return -50;
  }
 }
 /**
  *示範函數
  *根據使用者輸入的路徑對檔案進行解壓
  */
 public static void main(String args[]) throws Exception {

  long flag;                   //返回標誌
  String inPath,releasePath;

  //獲得使用者輸入資訊
  BufferedReader userInput = new BufferedReader(
           new InputStreamReader(System.in));
  System.out.println("請輸入zip檔案路徑:");
  inPath = userInput.readLine();
  System.out.println("請輸入儲存路徑:");
  releasePath = userInput.readLine();
  userInput.close();

  //執行解壓縮
  zipFileRelease pceraZip = new zipFileRelease(inPath,releasePath);
  flag = pceraZip.releaseHandle();

  //出錯資訊列印
  if (flag == 0) System.out.println("釋放成功!!!");
  if (flag == -1) System.out.println("您所要解壓的檔案不存在!");
  if (flag == -2) System.out.println("您所要解壓的檔案不能被開啟!");
  if (flag == -3) System.out.println("您所要釋放的路徑不存在!");
  if (flag == -4) System.out.println("您所建立檔案目錄失敗!");
  if (flag == -5) System.out.println("寫入檔案失敗!");
  if (flag == -6) System.out.println("檔案已經存在!");
  if (flag == -50) System.out.println("檔案讀取異常!");
 }
}



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。