Andy Lanng Ответов: 1

Возврат потокового файла из zip-файла


Привет,

У меня есть куча изображений, хранящихся в zip-файлах. Я пытаюсь вернуть изображение из моего приложения Web Api 2. Может ли кто-нибудь предложить умный способ вернуть поток непосредственно из zip-архива, а затем избавиться от него (код ниже)?

Я подумываю о том, чтобы отказаться от плана " zip " и сохранить изображения в виде плоских файлов, но их буквально миллионы. Я беспокоюсь о том, сколько места они займут на диске.

Я ищу самый быстрый способ доставить изображение с момента запроса. Это моя главная забота об этом PoC.

Спасибо ^_^
Энди

Что я уже пробовал:

В настоящее время я копирую поток в поток памяти:

Я храню путь как "C:\ImageLib\1045.zip\GS67801_POS_Image.jpg"
private Stream GetImageByItemCode(string itemCode)
        {
            var item = ItemType.SelectByItemCode(itemCode).FirstOrDefault();
            if (item == null)
                return null;

            if (item.PosImagePath == null)
                return null;
            MemoryStream ms = new MemoryStream();
            if (item.PosImagePath.IndexOf(".zip") > 0)
            {
                var zipPath = item.PosImagePath.Substring(0, item.PosImagePath.IndexOf(".zip") + 4);
                var filename = item.PosImagePath.Substring(item.PosImagePath.IndexOf(".zip") + 5);
                var zipFile = ZipFile.Open(zipPath, ZipArchiveMode.Read);

                var entry = zipFile.Entries.Where(e => e.FullName == filename).FirstOrDefault();
                if (entry == null)
                    return null;

                entry.Open().CopyTo(ms);

                ms.Seek(0, SeekOrigin.Begin);
            }
            return ms;
        }

Это PoC, поэтому я не оптимизировал способ хранения имени файла atm. С этой деталью я разберусь позже.

Этот метод используется для создания HttpResponse:
public HttpResponseMessage GetImageImg(string itemCode, int size)
{
    Stream imageStream = GetImageByItemCode(itemCode);

    //var imageArray = ResizeImage(image, size);



    var response = Request.CreateResponse();
    if (imageStream == null)
    {
        return response;
    }
    response.Content = new StreamContent(imageStream);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

который возвращается моим контроллером здесь:

[Route("{itemCode}/{size:int?}")]
   public object GetImage(string itemCode, int size = 1)
   {
       var query = Request.GetQueryNameValuePairs().ToDictionary(p => p.Key.ToLower(), p => p.Value.ToLower());
       var format = "img";
       if (query.ContainsKey("format"))
       {
           format = query["format"];
       }
       switch (format)
       {
           default:
               return GetImageImg(itemCode, size);
       }
   }

Не беспокойтесь обо всей этой ерунде с форматированием. В конце концов размер / формат будут храниться в моей библиотеке как отдельные файлы.

1 Ответов

Рейтинг:
2

Dave Kreskowiak

JPG-это уже сжатый формат.

Насколько эти изображения сжимаются в .ZIP-файлы? Большинство графических форматов, таких как PNG, JPG, TIFF, ... уже сжаты, так что вы на самом деле не получаете много, помещая их .сжатый файл. Возможно, вы получаете сжатие от 1% до 2%.

Или, если вы используете несжатый формат, например BMP, можете ли вы обойтись без преобразования и использования сжатой версии? Некоторые форматы и настройки будут потеряны, а другие-нет. Все зависит от образов.

Что касается потоковой операции с файлом, то это зависит от используемой вами ZIP-библиотеки. Если он находится в пространстве имен System. IO. Compression, встроенном в .NET Framework, вы можете получить запись для файла с помощью Одному.Метод GetEntry (String) (System. IO. Compression)[^] метод для получения объекта ZipArchiveEntry, а затем использовать ZipArchiveEntry.Открытый метод (System.IO.Compression)[^] метод получения потока.


Andy Lanng

A: вы не читали мое текущее решение
Б: ваш ответ дает мне не больше информации, чем я дал
C: jpeg имеет уровни сжатия. Вы можете легко достичь гораздо большего в молнии. Кроме того, каждый zip-файл содержит сотни изображений, чтобы, скорее всего, улучшить соотношение. Попробуйте 80% степень сжатия
Извините за резкость, но вы действительно не ответили на мой вопрос о том, как вернуть поток из ZipArchiveEntry.open() перед удалением архива

Dave Kreskowiak

Извините, я пропустил код.

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

Вы уже возвращаете поток как можно быстрее. Поскольку исходный ZIP-файл в данный момент закрыт и удален, содержимое должно быть перенесено в другой поток, который будет жить достаточно долго.

У вас есть только один способ быстрее вернуть содержимое-это иметь файлы не в ZIP-файле, а на диске и просто заставить веб-сервер вернуть файл непосредственно по URL-адресу.

Если пространство является проблемой, попробуйте преобразовать изображения в другой формат и сжатие. Да, я знаю, что у вас их "миллионы".

Andy Lanng

Да , к такому выводу я и пришел. Изображения должны быть высокого разрешения (не знаю, почему они выбрали jpg!). Пространство не должно быть проблемой. Просто добавляет к стоимости.

Спасибо, что перезвонили мне ^_^

Dave Kreskowiak

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

Мы мигрировали со старого (кусок дерьма!) сайта на тот, который переписали с нуля. На старом сайте было около 780 ГБ изображений всех типов, таких как JPG, BMP, некоторые TIFF ... У нас были тонны БМП, и они самые худшие, так как они 32bpp и никакого сжатия.

После тестирования на некоторых наборах этих изображений я обнаружил, что в нашем случае PNG лучше всего работает для сжатия изображений вниз и без потери качества изображения. ВАШ ПРОБЕГ МОЖЕТ ВАРЬИРОВАТЬСЯ.

Преобразование всех наших изображений в PNG привело к тому, что 780 ГБ уменьшились до 2 ГБ, а рядом с ними появились миниатюры размером 80х80! У нас есть контроллер и библиотека, которая автоматически преобразует любое изображение, загруженное в любом формате, в PNG перед отправкой в базу данных.

По уважительным причинам, в которые я не могу вдаваться, мы храним изображения в базе данных, а не в файловой системе сервера. Это не самый эффективный способ хранения изображений, но это то, что нам нужно.