在 C# 解壓縮整個檔案(可覆寫舊檔)

最近在用 C# 寫程式,處理到解壓縮的部份,雖然它有很方便的方法

 

ZipFile.ExtractToDirectory(壓縮檔, 目的目錄);

 

不過實測後,發現一個問題,若目的已有相同的檔案,則會産生錯誤,所以要自行解決這個問題。

 

我原本想過三個方法。

 

第一個是先解壓縮在其它目錄,再全部移到指定的目錄,但缺點是可能會佔用太多空間。如果原本的檔案就很大,要解開的檔案也很大,硬碟空間不夠的情況,解壓縮就會失敗,所以這個方法就先放棄了。

 

第二個方去是先逐一檢查檔案是否存在,存在就先刪除。如此一來,先把舊檔案刪掉,空間就會多一點,比較不擔心空間不夠的問題,最後再用 ZipFile.ExtractToDirectory 解壓縮至指定目錄。

 

第三個方法同上,只是突然想到,乾脆在檢查是否存在之後,就直接解壓縮該檔案,不用等到最後再全部解壓縮。

 

也就是利用各檔案 ZipArchiveEntry 的 ExtractToFile 功能。

 

經實測第三個方法比較快一點,就不使用第二種了。使用這個方法要注意,若是不存在的目錄,也要先建立起來。

 

最後又發現,ZipArchiveEntry 的 ExtractToFile 有 overwrite 的參數,所以原本是自行刪檔的片段


 

 

if(overwrite) {

    if (File.Exists(desFileName)) {

        File.Delete(desFileName);

        file.ExtractToFile(desFileName);

    }

}

 

 

可以改成

 

 

if(overwrite) {

    file.ExtractToFile(desFileName, true);

}


 

最後程式如下:

 

 

string zipFile = @"d:\A.zip"; // 待解壓縮的檔案

string outDir = @"d:\Temp"; // 解壓縮目的目錄

UnzipToDirectory(zipFile, outDir, true);

 

// 若已存在的檔案不想被覆蓋,overwrite 可設為 false

void UnzipToDirectory(string zipFile, string outDir, bool overwrite = true)

{

    ZipArchive archive = ZipFile.OpenRead(zipFile);

    foreach (ZipArchiveEntry file in archive.Entries)

    {

        // file.Name == "" 表示 file 為目錄

        if(file.Name == "") {

            string desPath = Path.Combine(outDir, file.FullName);

 

            // 目錄不存在就要建立

            if (!Directory.Exists(desPath)) {

                Directory.CreateDirectory(desPath);

            }

        } else {

            // file 為檔案

            string desFileName = Path.Combine(outDir, file.FullName);

 

            // 可覆寫就直接解壓縮

            if (overwrite) {

                file.ExtractToFile(desFileName, true);

            } else {

                // 不可覆寫就要先判斷檔案是否存在,不存在才解壓縮

                if (!File.Exists(desFileName)) {

                    file.ExtractToFile(desFileName);

                }

            }

        }

    }

}

 

 

重要度:
文章分類:

發表新回應