לפני כמה שבועות ראיתי פרויקט שמשתמש ב-ZIP בצורה מכובדת.
חלטתי שזה הזמן לספר את האמת על ZIP בגרסה האחרונה של NET .
עד לא מזמן לא היה פתרון בתוך ה-framework לעבודה עם כיווץ ZIP.
המון מפתחים בעולם השתמשו בקומפוננטות של צד שלישי, למשל “DotnetZip”.
ב-NET 4.5. מיקרוסופט סוף סוף הוסיפו מימוש לתוך ה-framework
את המחלקה הרלוונטית אפשר למצוא ב System.IO.Compression
דוגמא 1:
1 |
ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Optimal, isIncludeBaseDirectory); |
– startPath–נתיב לתיקיה שעליה רוצים לעבוד
למשל, c:\zipexample\start
– zipPath–נתיב לקובץ שיווצר מסוג zip (כולל מסלול מלא של תיקיה ושם קובץ)
למשל, c:\zipexample\result.zip
– CompressionLevel – רמת דחיסה
למשל, אופטימאלי , מהיר ביותר או ללא דחיסה
– isIncludeBaseDirectory – ערך בוליאני, האם בזמן יצירת קובץ zip לכלול את התיקיה הראשית
דוגמא 2:
1 |
ZipFile.ExtractToDirectory(zipPath, extractPath); |
– zipPath–נתיב לקובץ zip שאותו רוצים לפתוח ולבטל את הדחיסה (uncompressed).
למשל, c:\zipexample\result.zip
– extractPath – נתיב לאן רוצים לפתוח את הקובץ
למשל, c:\zipexample\extract
טיפ\באג השבוע :
אם אני רוצה לעשות מניפולציה על קובץ zip.
למשל, אם יש קובץ ששמו test2 בתוך הארכיב – למחוק אותו.
אז הקוד הבא,
1 2 3 4 5 6 7 8 9 |
ZipArchive za = ZipFile.Open(zipPath, ZipArchiveMode.Update); foreach (var entry in za.Entries) { if (entry.Name.Contains("test2")) { entry.Delete(); } } |
מייצר באג!!!
Collection was modified; enumeration operation may not execute.
אז הפתרון הוא לעשות loop על אותם Entries.
1 2 3 4 5 6 7 8 9 |
for (int i = 0; i < za.Entries.Count; i++) { if (za.Entries[i].Name.Contains("test2")) { za.Entries[i].Delete(); i--; } } |
מצרף פה קוד מלא של הפוסט הזה:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.IO.Compression; namespace ZipSample { class Program { static void Main(string[] args) { string startPath = @"c:\zipexample\start"; string zipPath = @"c:\zipexample\result.zip"; string extractPath = @"c:\zipexample\extract"; bool isIncludeBaseDirectory = true; ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Optimal, isIncludeBaseDirectory); ZipFile.ExtractToDirectory(zipPath, extractPath); ZipArchive za = ZipFile.Open(zipPath, ZipArchiveMode.Update); //foreach (var entry in za.Entries) //{ // if (entry.Name.Contains("test2")) // { // entry.Delete(); // } //} for (int i = 0; i < za.Entries.Count; i++) { if (za.Entries[i].Name.Contains("test2")) { za.Entries[i].Delete(); i--; } } } } } |
מקווה שנהנתם 🙂