2015-06-24 5 views
1

Я искал решение для своей проблемы, но, похоже, никто не стремится к тому, чего я пытаюсь достичь.Как воссоздать Zip-файл из MemoryStream

Моя проблема в том, что у меня есть файлы Zip, хранящиеся в хранилище Azure Blob, теперь для безопасности у нас есть действие контроллера API2, которое обеспечивает эти файлы zip, а не позволяет напрямую загружать файлы. Это действие будет извлекать blob и загружать его в поток, чтобы его можно было упаковать в пределах HTTPResponseMessage.

Все вышеперечисленные работы, однако, когда я пытаюсь воссоздать zip-файл, мне сообщают, что он поврежден. На данный момент я просто пытаюсь заставить сервер (работающий на localhost) создавать zip-файл, тогда как эндшпиль должен иметь удаленные клиентские приложения (я уверен, что решение моей проблемы на сервере будет одинаковым .

public class FileActionResult : IHttpActionResult 
{ 
    private HttpRequestMessage _request; 
    private ICloudBlob _blob; 

    public FileActionResult(HttpRequestMessage request, ICloudBlob blob) 
    { 
    _request = request; 
    _blob = blob; 
    } 

    public async Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken) 
    { 
    var fileStream = new MemoryStream(); 
    await _blob.DownloadToStreamAsync(fileStream); 

    var byteTest = new byte[fileStream.Length]; 
    var test = fileStream.Read(byteTest, 0, (int)fileStream.Length); 

    try 
    { 
     File.WriteAllBytes(@"C:\testPlatFiles\test.zip", byteTest); 
    } 
    catch(ArgumentException ex) 
    { 
     var a = ex; 
    } 

    var response = _request.CreateResponse(HttpStatusCode.Accepted); 
    response.Content = new StreamContent(fileStream); 
    response.Content.Headers.ContentLength = _blob.Properties.Length; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue(_blob.Properties.ContentType); 
    //set the fileName 
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
    { 
     FileName = _blob.Name, 
     Size = _blob.Properties.Length 
    }; 
    return response; 
    } 
} 

Я посмотрел в библиотеки Zip, чтобы увидеть, если какой-либо представить решение для преобразования потока молнии обратно в почтовый файл, но все, что я могу найти чтение архивных файлов на потоки, или создание в целях предоставления файла загрузки вместо filecreate.

Любая помощь будет высоко ценится, спасибо.

+1

В зависимости от размера файла zip? если вы попробуете небольшой zip-файл, менее 1 Мб, у вас все еще есть проблема? Вы также можете попробовать fileStream.ToArray(), это даст вам байт [] arryay с содержимым вашего потока. –

+0

@AlexShapovalov Хорошо, поэтому .ToArray() работал для меня, в основном моя проблема в том, что filestream.Read работает неправильно, он записывает правильное количество байтов, но все они имеют значение 0. ToArray() создает массив байтов такого же размера, но байты фактически имеют значения. Моя следующая проблема заключается в том, что на моем клиенте поток - это WebConnectionStream, поэтому превращение его в MemoryStream может быть более неприятным, но я это сделаю сейчас! :) –

ответ

2

Вы используете DotNetZip. Его ZipFile класс имеет статический фабричный метод, который должен делать то, что вы хотите:. ZipFile.Read(Stream zipStream) читает данный поток в виде архива, и дает вам обратно ZipFile экземпляр (который вы можете использовать для любой другой

Однако, если ваш Stream содержит необработанные данные zip и все, что вы хотите сделать, это сохранить его на диске, вы должны просто записать байты прямо на диск.

Если вы получаете ошибки «zip-файла повреждены», я бы посмотрел на кодировку содержимого, используемую для отправки данных в Azure и кодировку содержимого, с которой она отправлена ​​обратно. Вы должны отправить ее до Azure с типом контента application/zip или application/octet-stream и, возможно, добавить метаданные к Azure blob чтобы отправить его таким же образом.

+0

Спасибо за понимание, я дам DotNetZip завтра (пытался SharpZipLib и не мог найти то, что искал). Что касается типа контента, загрузка сохраняет тип контента из RequestMessage, а затем извлекается из Blob, как вы можете видеть в фрагменте, поэтому он должен * быть в порядке. –

+0

Отметить как ответ, так как мне пришлось использовать DotNetZip portable для распаковки из моего файла. В конце концов, это была слепая глупость с моей стороны. Фильтр на сервере (который затем упаковывается как StreamContent) имеет его положение, установленное в конец потока. Установка его на 0, и мой код работал отлично. Я пропустил это, потому что на моем потребительском коде, свойство позиции не реализовано, поэтому я не смог его оценить! Спасибо. –

Смежные вопросы