मैं बिना # 3rd-API API का उपयोग किए C # में एक फ़ाइल कैसे करूं?


175

मुझे पूरा यकीन है कि यह सिर्फ एक मिनट के लिए मेरे साथ एक डुप्लिकेट नहीं है।

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

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



1
@ चेसो: हाँ, एक ASPX पृष्ठ से।
एस्टेबान अरया

1
मुझे यह उदाहरण तब उपयोगी लगा जब मैं कुछ सप्ताह पहले इसी चीज़ की खोज कर रहा था: syntaxwarriors.com/2012/…
JensB

2
4.5 फ्रेमवर्क का उपयोग करने पर, अब ZipArchive और ZipFile कक्षाएं हैं।
गांगेयजेलो

किसी ने DotNetZip का इस्तेमाल किया ??
हॉट लाइक्स

जवाबों:


85

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

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


1
ओह एसओ, आई लव यू! धन्यवाद ब्रायन; यूओ ने हमें बहुत सारे सिरदर्द और कुछ $ $ $ बचाए।
एस्टेबन अरया

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

ध्यान दें कि ZipPackage मौजूदा ज़िपित पैकेज में संलग्न नहीं हो सकता है।
53मेगामैन

आह: "प्रकार या नाम स्थान" पैकेजिंग "नामस्थान" System.IO "में मौजूद नहीं है।
Hot Licks

2
(उपरोक्त "उच्छ्वास" का उत्तर: "संदर्भ" खोलें और जोड़ें (अतार्किक रूप से पर्याप्त) "विन्डोज़बेस"।)
हॉट लिक्स

307

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

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

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

आपको संदर्भ जोड़ने की आवश्यकता है:

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

.NET Core लक्ष्यीकरण net46 के लिए, आपको निर्भरताएँ जोड़ने की आवश्यकता है

  • System.IO.Compression
  • System.IO.Compression.ZipFile

उदाहरण के प्रोजेक्ट। json:

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

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

.NET कोर 2.0 के लिए, केवल एक साधारण स्टेटमेंट का उपयोग करना है, जिसकी आवश्यकता है:

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

4
यह कैसे अधिक चढ़ाव नहीं मिला है? इसका सीधा जवाब है।
मैट Cashatt

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

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

5
बस मामले में यह किसी को भी मदद करता है, दूसरा तर्क फ़ाइल प्रविष्टि है। यह वह पथ है जिस पर फ़ाइल unzip फ़ोल्डर के सापेक्ष निकाली जाएगी। विंडोज 7 में, मैंने पाया कि अगर फ़ाइल प्रविष्टि एक पूर्ण पथ है, उदाहरण के लिए, @ "D: \ Temp \ file1.pdf", तो मूल Windows निष्कासन विफल रहता है। यदि आप केवल Directory.GetFiles () से उत्पन्न फ़ाइल नाम का उपयोग करते हैं तो आप इस समस्या में भाग सकते हैं। फ़ाइल प्रविष्टि तर्क के लिए Path.GetFileName () का उपयोग करके फ़ाइल नाम निकालने के लिए सबसे अच्छा है।
मनीष

2
मुझे यह 4.5.2 में नहीं मिल रहा है?
user3791372

11

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

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

[Content_Types] .xml फ़ाइल के बारे में अधिक जानकारी यहां पाई जा सकती है: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx

यहां [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>

और एक ज़िप फ़ाइल बनाने के लिए सी #:

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)); 
            } 
        } 
    } 

ध्यान दें:


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

9
    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");
    }

HttpContext.Current.equest को प्राप्त करने के बाद मैं sourceFileName कैसे प्राप्त कर सकता हूं?
ओलिवरटेक

अधिक एक फ़ाइल संपीड़ित करें?
किकेनेट

1

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

    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);
    }
}

0

विंडोज की तरह दिखता है केवल आपके करते हैं हो सकता है यह ...

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


0

इन 4 कार्यों को अपनी परियोजना में जोड़ें:

        public const long BUFFER_SIZE = 4096;
    public static void AddFileToZip(string zipFilename, string fileToAdd)
    {
        using (Package zip = global::System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
        {
            string destFilename = ".\\" + Path.GetFileName(fileToAdd);
            Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
            if (zip.PartExists(uri))
            {
                zip.DeletePart(uri);
            }
            PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);
            using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
            {
                using (Stream dest = part.GetStream())
                {
                    CopyStream(fileStream, dest);
                }
            }
        }
    }
    public static void CopyStream(global::System.IO.FileStream inputStream, global::System.IO.Stream outputStream)
    {
        long bufferSize = inputStream.Length < BUFFER_SIZE ? inputStream.Length : BUFFER_SIZE;
        byte[] buffer = new byte[bufferSize];
        int bytesRead = 0;
        long bytesWritten = 0;
        while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0)
        {
            outputStream.Write(buffer, 0, bytesRead);
            bytesWritten += bytesRead;
        }
    }
    public static void RemoveFileFromZip(string zipFilename, string fileToRemove)
    {
        using (Package zip = global::System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
        {
            string destFilename = ".\\" + fileToRemove;
            Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
            if (zip.PartExists(uri))
            {
                zip.DeletePart(uri);
            }
        }
    }
    public static void Remove_Content_Types_FromZip(string zipFileName)
    {
        string contents;
        using (ZipFile zipFile = new ZipFile(File.Open(zipFileName, FileMode.Open)))
        {
            /*
            ZipEntry startPartEntry = zipFile.GetEntry("[Content_Types].xml");
            using (StreamReader reader = new StreamReader(zipFile.GetInputStream(startPartEntry)))
            {
                contents = reader.ReadToEnd();
            }
            XElement contentTypes = XElement.Parse(contents);
            XNamespace xs = contentTypes.GetDefaultNamespace();
            XElement newDefExt = new XElement(xs + "Default", new XAttribute("Extension", "sab"), new XAttribute("ContentType", @"application/binary; modeler=Acis; version=18.0.2application/binary; modeler=Acis; version=18.0.2"));
            contentTypes.Add(newDefExt);
            contentTypes.Save("[Content_Types].xml");
            zipFile.BeginUpdate();
            zipFile.Add("[Content_Types].xml");
            zipFile.CommitUpdate();
            File.Delete("[Content_Types].xml");
            */
            zipFile.BeginUpdate();
            try
            {
                zipFile.Delete("[Content_Types].xml");
                zipFile.CommitUpdate();
            }
            catch{}
        }
    }

और उन्हें इस तरह से उपयोग करें:

foreach (string f in UnitZipList)
{
    AddFileToZip(zipFile, f);
    System.IO.File.Delete(f);
}
Remove_Content_Types_FromZip(zipFile);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.