2016-03-31 5 views
5

में संपादित ZipArchive मैं एक XmlDocument फ़ाइल एक ज़िप फ़ाइल में निहित संपादित करने के लिए कोशिश कर रहा हूँ:स्मृति नेट

var zip = new ZipArchive(myZipFileInMemoryStream, ZipArchiveMode.Update); 
var entry = zip.GetEntry("filenameToEdit"); 
using (var st = entry.Open()) 
{ 
    var xml = new XmlDocument(); 
    xml.Load(st); 
    foreach (XmlElement el in xml.GetElementsByTagName("Relationship")) 
    { 
     if(el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat")){ 
      el.SetAttribute("Target", path); 
     } 
    } 
    xml.Save(st); 
} 

इस कोड को क्रियान्वित करने के बाद निहित फ़ाइल नहीं बदला है। अगर xml.Save(st); के बजाय मैं डिस्क पर एक्सएमएल लिखता हूं, तो मुझे संपादित किया गया है।

संपादित फ़ाइल को ज़िप पर क्यों नहीं लिखा गया है? मैं इसे कैसे ठीक करूं?

संपादित करें:

मैं कोड अद्यतन:

var tmp = new MemoryStream(); 
using (var zip = new ZipArchive(template, ZipArchiveMode.Read, true)) 
{ 
    var entry = zip.GetEntry("xml"); 
    using (var st = entry.Open()) 
    { 
     var xml = new XmlDocument(); 
     xml.Load(st); 
     foreach (XmlElement el in xml.GetElementsByTagName("Relationship")) 
     { 
      if (el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat")) 
      { 
       el.SetAttribute("Target", path); 
      } 
     } 
     xml.Save(tmp); 
    } 
} 
using (var zip = new ZipArchive(template, ZipArchiveMode.Update, true)) 
{ 
    var entry = zip.GetEntry("xml"); 
    using (var st = entry.Open()) 
    { 
     tmp.Position = 0; 
     tmp.CopyTo(st); 
    } 
} 

इस तरह से ज़िप फ़ाइल संपादित किया जाता है में, लेकिन यह केवल तभी कारगर साबित धाराओं की लंबाई के बराबर है। यदि tmp कम है st शेष फ़ाइल में अभी भी है ...

संकेत?

 MemoryStream saveStream = new MemoryStream(); 

     ZipFile arrangeZipFile = new ZipFile(); 
     arrangeZipFile.AddEntry("test.xml", "content..."); 
     arrangeZipFile.Save(saveStream); 

     saveStream.Seek(0, SeekOrigin.Begin); 
     saveStream.Flush(); // might be useless, because it's in memory... 

उसके बाद मैं MemoryStream अंदर कोई मान्य ज़िप है:

+0

मैं आपको ज़िप को कहीं भी नहीं देख रहा हूं :) – Luaan

+0

मैंने डिस्क पर 'myZipFileInMemoryStream' को सहेजने के हिस्से को छोड़ दिया। संपादित भाग को स्ट्रीम में शामिल नहीं किया जाना चाहिए? – Emaborsa

+0

स्पष्ट रूप से, यह होना चाहिए - 'स्ट्रीम को पुनर्प्राप्त करने के बाद, आप स्ट्रीम से पढ़ या लिख ​​सकते हैं। जब आप स्ट्रीम में लिखते हैं, तो आपके द्वारा प्रविष्टि में किए गए संशोधन ज़िप संग्रह में दिखाई देंगे। (एमएसडीएन)। लेकिन आपको स्ट्रीम - 'st.Position = 0'' को रिवाइंड करना होगा, अन्यथा आप पुराने एक्स के अंत में नया एक्सएमएल जोड़ रहे हैं। क्या यह समस्या हो सकती है? :) – Luaan

उत्तर

0

मैं एक ज़िप InMemory (DotNetZip लाइब्रेरी का प्रयोग करके) बनाने के लिए इस कोड का उपयोग करें। मुझे यकीन नहीं है कि मैंने फ्लश() क्यों जोड़ा - मुझे लगता है कि यह अनावश्यक है।

मौजूदा ज़िप को संपादित करने के लिए आप इसे मेमोरीस्ट्रीम में पढ़ सकते हैं और "नया ज़िपफाइल()" "नया ज़िपफाइल (बाइटएरे ...)" बनाने के बजाय इसे पढ़ सकते हैं।

+0

क्या यह काम करता है भले ही 'test.xml' alredy मौजूद है? अगर मैं फाइल को सबफ़ोल्डर में रखना चाहता हूं तो क्या होगा? के लिए 'सामग्री' क्या है? – Emaborsa

+0

arrangeZipFile.AddEntry ("test.xml", "content ..."); => ज़िप के अंदर एक नई "text.xml" फ़ाइल तैयार करेगी, जो दी गई सामग्री के साथ स्मृति में संग्रहीत है। यदि आप एक प्रविष्टि को अपडेट करना चाहते हैं तो बस अपडेटएन्ट्री विधि का उपयोग करें। उपफोल्डर के लिए: कम से कम DotNetZip केवल दिए गए पथ का उपयोग करेगा, उदा। यदि आप सबफ़ोल्डर बनाना चाहते हैं तो बस इसे इस तरह नाम दें: AddEntry ("subfolder/test.xml" ..) –