2009-06-02 15 views
139

मुझे यकीन है कि यह एक डुप्लिकेट नहीं है इसलिए मेरे साथ बस एक मिनट के लिए भालू।कोई तीसरे पक्ष के एपीआई का उपयोग करते हुए, मैं सी # में फ़ाइल कैसे ज़िप करूं?

मैं किसी भी तृतीय पक्ष पुस्तकालयों का उपयोग किए बिना प्रोग्राम (सी #) एक फ़ाइल (विंडोज़ में) कैसे ज़िप कर सकता हूं? मुझे एक मूल विंडोज़ कॉल या ऐसा कुछ चाहिए; मैं वास्तव में एक प्रक्रिया शुरू करने के विचार को नापसंद करता हूं, लेकिन अगर मुझे पूरी तरह से करना होगा तो मैं करूँगा। एक PInovke कॉल बहुत बेहतर होगा।

विफल होने से, मैं आपको बताता हूं कि मैं वास्तव में क्या करने की कोशिश कर रहा हूं: मुझे उपयोगकर्ता को एक ही अनुरोध में दस्तावेज़ों का संग्रह डाउनलोड करने की क्षमता चाहिए। इसे पूरा करने के तरीके पर कोई विचार?

+1

डाउनलोड? – Cheeso

+1

@ चेससो: हां, एएसपीएक्स पेज से। –

+1

मुझे यह उदाहरण उपयोगी पाया गया जब मैं कुछ हफ्ते पहले एक ही चीज़ की खोज कर रहा था: http://www.syntaxwarriors.com/2012/zip-files-using-c-net-without-any-extra-libraries/ – JensB

उत्तर

80

क्या आप .NET 3.5 का उपयोग कर रहे हैं? आप ZipPackage कक्षा और संबंधित कक्षाओं का उपयोग कर सकते हैं। फ़ाइल सूची को बस ज़िप करने से कहीं अधिक है क्योंकि यह आपके द्वारा जोड़े गए प्रत्येक फ़ाइल के लिए एक एमआईएमई प्रकार चाहता है। यह वही हो सकता है जो आप चाहते हैं।

मैं वर्तमान में एक ही फाइल के लिए एक ही फाइल में कई संबंधित फाइलों को संग्रहित करने के लिए एक ही समस्या के लिए इन कक्षाओं का उपयोग कर रहा हूं। हम डाउनलोड फ़ाइल को हमारे डेस्कटॉप ऐप से जोड़ने के लिए एक फ़ाइल एक्सटेंशन का उपयोग करते हैं। एक छोटी सी समस्या में हमने भाग लिया था कि ज़िप फ़ाइलों को बनाने के लिए केवल 7-ज़िप जैसे किसी तृतीय-पक्ष टूल का उपयोग करना संभव नहीं है क्योंकि क्लाइंट साइड कोड इसे नहीं खोल सकता है - ज़िपपैकेज सामग्री प्रकार का वर्णन करने वाली एक छिपी हुई फ़ाइल जोड़ता है प्रत्येक घटक फ़ाइल और एक ज़िप फ़ाइल नहीं खोल सकता है अगर उस सामग्री प्रकार फ़ाइल गुम है।

+0

इसने मेरे लिए अतीत में अच्छा काम किया है। – David

+1

ओह तो, मैं तुमसे कैसे प्यार करता हूँ! धन्यवाद ब्रायन; Yuo बस हमें बहुत सी सिरदर्द और कुछ $$$ बचाया। –

+5

ध्यान दें कि यह हमेशा विपरीत में काम नहीं करता है। कुछ ज़िप फ़ाइलें ZipPackage क्लास का उपयोग करके पुनः बहाल नहीं करेंगे। ज़िपपैकेज के साथ बनाई गई फाइलें आपको अच्छी रहनी चाहिए। – Craig

0

विंडोज की तरह लग रहा केवल आपके this करते हैं हो सकता है ...

दुर्भाग्य से मुझे नहीं लगता कि आप एक अलग प्रक्रिया शुरू करने से जब तक आप एक तीसरे पक्ष के घटक के लिए जाने से बचने के लिए जा रहे हैं है।

4

एक .NET 2.0 ऐप के लिए मैंने SharpZipLib का उपयोग किया। उपयोग करने में आसान और खुला स्रोत।

+2

मैं कर सकता हूं तीसरे पक्ष के libs का उपयोग नहीं करते हैं। –

+11

शॉद ने थोड़ा और करीब से पढ़ा है। दोह!SharpZipLib अभी भी एक अच्छी लाइब्रेरी है जो इसके लायक है। –

+0

आप यहां नमूने पा सकते हैं: https://github.com/icsharpcode/SharpZipLib/wiki/Zip- नमूने – Spawnrider

11

मैं एक ही स्थिति में था, जो किसी तृतीय पक्ष लाइब्रेरी के बजाय .NET को चाहता था। ऊपर वर्णित एक अन्य पोस्टर के रूप में, बस ज़िपपैकेज क्लास (.NET 3.5 में पेश किया गया) का उपयोग करना पर्याप्त नहीं है। ZipPackage को काम करने के लिए एक अतिरिक्त फ़ाइल है जिसे संग्रह में शामिल किया जाना चाहिए। यदि यह फ़ाइल जोड़ा गया है, तो परिणामस्वरूप ज़िप पैकेज सीधे विंडोज एक्सप्लोरर से खोला जा सकता है - कोई समस्या नहीं।

आपको बस इतना करना है कि संग्रह के रूट में [Content_Types] .xml फ़ाइल को प्रत्येक फ़ाइल एक्सटेंशन के लिए "डिफ़ॉल्ट" नोड के साथ जोड़ना है जिसमें आप शामिल करना चाहते हैं। एक बार जोड़ा गया, मैं विंडोज एक्सप्लोरर से पैकेज ब्राउज़ कर सकता हूं या प्रोग्रामेटिक रूप से डिकंप्रेस कर सकता हूं और इसकी सामग्री पढ़ सकता हूं।

[CONTENT_TYPES] .xml फ़ाइल पर अधिक जानकारी यहां पाया जा सकता है:

<?xml version="1.0" encoding="utf-8" ?> 
<Types xmlns= 
    "http://schemas.openxmlformats.org/package/2006/content-types"> 
    <Default Extension="xml" ContentType="text/xml" /> 
    <Default Extension="htm" ContentType="text/html" /> 
    <Default Extension="html" ContentType="text/html" /> 
    <Default Extension="rels" ContentType= 
    "application/vnd.openxmlformats-package.relationships+xml" /> 
    <Default Extension="jpg" ContentType="image/jpeg" /> 
    <Default Extension="png" ContentType="image/png" /> 
    <Default Extension="css" ContentType="text/css" /> 
</Types> 

: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx

यहाँ (वास्तव में नामित किया जाना चाहिए) फ़ाइल [CONTENT_TYPES] .xml का एक नमूना है और सी # एक ज़िप फ़ाइल बनाने के लिए:

var zipFilePath = "c:\\myfile.zip"; 
var tempFolderPath = "c:\\unzipped"; 

    using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read)) 
    { 
     foreach (PackagePart part in package.GetParts()) 
     { 
      var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/'))); 
      var targetDir = target.Remove(target.LastIndexOf('\\')); 

      if (!Directory.Exists(targetDir)) 
       Directory.CreateDirectory(targetDir); 

      using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read)) 
      { 
       source.CopyTo(File.OpenWrite(target)); 
      } 
     } 
    } 

नोट:

+11

अच्छा नमूना, लेकिन यह एक ज़िप फ़ाइल नहीं बनाता है। यह एक मौजूदा फाइल को अनजिप करता है। –

+0

+1 System.IO.Compression संदर्भ –

216

मैं कैसे प्रोग्राम के (सी #) किसी भी तीसरे पक्ष के पुस्तकालयों का उपयोग किए बिना (Windows में) एक फ़ाइल ज़िप कर सकते हैं?

यदि 4.5+ फ्रेमवर्क का उपयोग करते हैं, तो अब ZipArchive और ZipFile कक्षाएं हैं।

  • System.IO.Compression
  • System.IO.Compression.FileSystem

नेट कोर को निशाना बनाने के लिए:

using (ZipArchive zip = ZipFile.Open("test.zip", ZipArchiveMode.Create)) 
{ 
    zip.CreateEntryFromFile(@"c:\something.txt", "data/path/something.txt"); 
} 

आप के लिए संदर्भ जोड़ने की जरूरत net46, आपको

के लिए निर्भरता जोड़ने की आवश्यकता है
  • System.IO.Compression
  • System.IO.Compression.ZipFile

उदाहरण project.json:

"dependencies": { 
    "System.IO.Compression": "4.1.0", 
    "System.IO.Compression.ZipFile": "4.0.1" 
}, 

"frameworks": { 
    "net46": {} 
} 

नेट कोर 2.0 के लिए, बस एक जोड़ने कथन का उपयोग करना सरल है:

    System.IO.Compression का उपयोग कर
  • ;
+3

के लिए यह कैसे अधिक upvotes प्राप्त नहीं किया है? यह एकमात्र सीधा जवाब है। –

+9

क्योंकि सवाल पांच साल पुराना है, जबकि यह उत्तर केवल दो महीने पुराना है। Derp :-P – Heliac

+3

@heliac अभी भी Stackoverflow thingie एक प्रश्न और उत्तर भंडार होना चाहिए और आत्मा में सबसे अच्छा जवाब shoudl शीर्ष पर होना चाहिए ... (अरे, मुझे पता था कि यह काम नहीं करता है) – Offler

1

बंद आधार पर साइमन मैकेंजी के जवाब to this question, मैं इस तरह के तरीकों की एक जोड़ी उपयोग करने का सुझाव चाहते हैं: एक वेब पेज से

public static void ZipFolder(string sourceFolder, string zipFile) 
    { 
     if (!System.IO.Directory.Exists(sourceFolder)) 
      throw new ArgumentException("sourceDirectory"); 

     byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 

     using (System.IO.FileStream fs = System.IO.File.Create(zipFile)) 
     { 
      fs.Write(zipHeader, 0, zipHeader.Length); 
     } 

     dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); 
     dynamic source = shellApplication.NameSpace(sourceFolder); 
     dynamic destination = shellApplication.NameSpace(zipFile); 

     destination.CopyHere(source.Items(), 20); 
    } 

    public static void UnzipFile(string zipFile, string targetFolder) 
    { 
     if (!System.IO.Directory.Exists(targetFolder)) 
      System.IO.Directory.CreateDirectory(targetFolder); 

     dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); 
     dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items; 
     dynamic destinationFolder = shellApplication.NameSpace(targetFolder); 

     destinationFolder.CopyHere(compressedFolderContents); 
    } 
} 
3
private static string CompressFile(string sourceFileName) 
    { 
     using (ZipArchive archive = ZipFile.Open(Path.ChangeExtension(sourceFileName, ".zip"), ZipArchiveMode.Create)) 
     { 
      archive.CreateEntryFromFile(sourceFileName, Path.GetFileName(sourceFileName)); 
     } 
     return Path.ChangeExtension(sourceFileName, ".zip"); 
    } 
संबंधित मुद्दे