2016-03-31 15 views
5

Tôi đang cố gắng để chỉnh sửa một tập tin XmlDocument chứa trong một file Zip:Sửa ZipArchive trong bộ nhớ NET

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

Sau khi thực thi mã này tập tin chứa là không thay đổi. NẾU thay vì xml.Save(st); Tôi viết xml vào đĩa, tôi đã chỉnh sửa.

Tại sao tệp được chỉnh sửa không được ghi vào mã zip? Làm thế nào để tôi sửa chữa nó?

EDIT:

tôi cập nhật mã:

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

Bằng cách này file zip được chỉnh sửa, nhưng nó chỉ hoạt động nếu chiều dài của dòng là như nhau. Nếu tmp ngắn hơn phần còn lại của st vẫn còn trong tệp ...

Gợi ý?

+0

Tôi không thấy bạn lưu mã zip ở bất kỳ đâu :) – Luaan

+0

Tôi đã bỏ qua phần lưu 'myZipFileInMemoryStream' vào đĩa. Phần không được chỉnh sửa có được đưa vào luồng không? – Emaborsa

+0

Rõ ràng, nó sẽ - 'Sau khi truy xuất luồng, bạn có thể đọc hoặc ghi vào luồng. Khi bạn ghi vào luồng, các sửa đổi bạn thực hiện cho mục nhập sẽ xuất hiện trong kho lưu trữ zip.' (MSDN). Nhưng bạn cũng phải tua lại luồng - 'st.Position = 0', nếu không bạn chỉ cần thêm XML mới vào cuối tệp cũ. Có thể đó là vấn đề? :) – Luaan

Trả lời

0

tôi sử dụng mã này để tạo ra một InMemory Zip (sử dụng thư viện DotNetZip):

 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... 

Sau đó tôi có một Zip hợp lệ bên trong MemoryStream. Tôi không chắc tại sao tôi lại thêm Flush() - tôi đoán điều này là thừa.

Để chỉnh sửa một Zip hiện có, bạn có thể đọc nó trong MemoryStream và thay vì tạo "ZipFile mới()" sử dụng "ZipFile mới (byteArray ...)".

+0

Tính năng này có hoạt động ngay cả khi có tồn tại 'almix' tồn tại? Điều gì xảy ra nếu tôi muốn đặt tệp trong thư mục con? Nội dung 'là gì? – Emaborsa

+0

arrangZipFile.AddEntry ("test.xml", "content ..."); => Sẽ tạo một tệp "text.xml" mới bên trong mã zip, được lưu trữ trong bộ nhớ, với nội dung đã cho. Nếu bạn muốn cập nhật một mục chỉ sử dụng phương pháp UpdateEntry. Đối với thư mục con: Ít nhất DotNetZip sẽ chỉ sử dụng đường dẫn đã cho, ví dụ: nếu bạn muốn tạo một thư mục con chỉ cần đặt tên theo cách đó: AddEntry ("subfolder/test.xml" ..) –

Các vấn đề liên quan