2015-02-20 2 views
1

Я пытаюсь создать ZIP с файлом из строки в памяти и сохранить его. Вот мой код:SharpZipLib - добавление ZipEntry в ZipFile вызывает ZipException

var zip = ZipFile.Create(Path.Combine(outputPath, fileName)); 
zip.BeginUpdate(); 

var fileStream = new MemoryStream(Encoding.Default.GetBytes(myStringVariable)); 
var outputMemStream = new MemoryStream(); 
var zipStream = new ZipOutputStream(outputMemStream); 
var zipEntry = new ZipEntry("file.html"); 

zipEntry.DateTime = DateTime.Now; 
zipStream.PutNextEntry(zipEntry); 
StreamUtils.Copy(fileStream, zipStream, new byte[4096]); 
zipStream.CloseEntry(); 
zip.Add(zipEntry); 

zip.CommitUpdate(); 
zip.Close(); 

Однако он ломается на zip.Add (zipEntry); и бросает исключение:

ZipException - запись не может иметь каких-либо данных

Как-то я не могу понять, что случилось.

ответ

3

Используемый метод переопределения ZipFile.Add предназначен для добавления каталогов, томов и т. Д. В zip-файл: он explicitly throws a ZipException, если вы передаете данные ZipEntry.

Согласно the documentation, если вы хотите добавить данные в память в ZipFile, вам необходимо использовать переопределение Add(IStaticDataSource dataSource, string entryName). Вам также необходимо создать реализацию IStaticDataSource (приведенная ниже на странице документации).

Так что ваш код будет что-то вроде:

void Main() 
{ 
    string outputPath = @"C:\Scratch\test.zip"; 
    string myStringVariable = "<html><head><title>Title</title></head><body>Hello World</body></html>"; 

    var zip = ZipFile.Create(outputPath); 
    zip.BeginUpdate(); 

    var fileStream = new MemoryStream(Encoding.Default.GetBytes(myStringVariable)); 

    var dataSource = new CustomStaticDataSource(); 
    dataSource.SetStream(fileStream); 

    zip.Add(dataSource, "file.html"); 

    zip.CommitUpdate(); 
    zip.Close(); 
} 

public class CustomStaticDataSource : IStaticDataSource { 
    private Stream _stream; 
    // Implement method from IStaticDataSource 
    public Stream GetSource() { 
     return _stream; 
    } 

    // Call this to provide the memorystream 
    public void SetStream(Stream inputStream) { 
     _stream = inputStream; 
     _stream.Position = 0; 
    } 
} 
+1

Отлично, это работает. Однако я должен признать, что это не интуитивное решение. – Andrzej