Как лучше всего работать с файлами в памяти на C #?

Я создаю веб-приложение ASP.NET, которое на лету создает презентации PowerPoint. У меня есть основы, но он создает реальные физические файлы на жестком диске. Это не кажется хорошей идеей для большого многопользовательского веб-приложения. Похоже, было бы лучше, если бы приложение создавало презентации в памяти, а затем передавало их обратно пользователю. Должен ли я работать с классом MemoryStream вместо того, чтобы манипулировать файлами? Я не совсем уверен, что понимаю разницу между работой с файлами и работой с потоками. Они как бы взаимозаменяемы? Может ли кто-нибудь указать мне на хороший ресурс для выполнения операций с типами файлов в памяти, а не на диске? Надеюсь, я достаточно хорошо об этом описал.

Кори


person Corey Burnett    schedule 04.05.2012    source источник
comment
Какой API вы используете для создания презентаций PowerPoint?   -  person user957902    schedule 04.05.2012
comment
Я использую классы из библиотеки DocumentFormat.OpenXML.   -  person Corey Burnett    schedule 04.05.2012


Ответы (3)


Вы пытаетесь принять решение, которое, по вашему мнению, влияет на производительность вашего приложения, на основе измерения «не кажется хорошей идеей», которое едва ли является научным. Было бы лучше реализовать оба варианта и сравнить, но сначала вы должны перечислить свои опасения по поводу любой из реализаций.

Вот несколько идей для начала:

  • на самом деле нет большой разницы между временными файлами и потоками в памяти. У обоих будет контент в физической памяти, если они достаточно малы, оба будут попадать на диск при нехватке памяти. Подумайте об использовании временного удаления при закрытии файлов для ваших файлов, если их очистка является основной проблемой.
  • ОС уже очень хорошо справляется с управлением большими файлами с помощью кеширования, поэтому необходимо убедиться, что чистое решение в памяти, по крайней мере, соответствует ему.
  • MemoryStream - не лучшая реализация для потоков разумного размера из-за его контракта «все данные в однобайтовом массиве» (см. Мой ответ на странице https://stackoverflow.com/a/10424137/477420).
  • Управление несколькими большими потоками в памяти (то есть для нескольких пользователей) - это развлечение для платформы x86, а для платформы x64 - меньшая проблема.
  • Некоторые API просто не предоставляют способ работы с классами на основе Stream и требуют физического файла.
person Alexei Levenkov    schedule 04.05.2012

Файлы и потоки похожи, да. Оба, по сути, передают массив byte ... один из памяти, другой с жесткого диска. Если используемый вами API позволяет создавать поток, вы можете легко сделать это и передать его пользователю с помощью объекта Response.

Следующий код возьмет объект памяти PowerPoint (вам нужно будет изменить его для вашего собственного API, но вы можете получить общее представление), сохраните его в MemoryStream, затем установите правильные заголовки и запишите поток в Response ( который затем позволит пользователю сохранить файл на свой локальный компьютер):

SaveFormat format = SaveFormat.PowerPoint2007;
Slideshow show = PowerPointWriter.Generate(report, format);
MemoryStream ms = new MemoryStream();
show.Save(ms, format);

Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-powerpoint";
Response.AddHeader("Content-Disposition", "attachment; filename=\"Slideshow.ppt\"");
Response.BinaryWrite(ms.ToArray());
Response.End();
person saluce    schedule 04.05.2012

Да, я бы порекомендовал MemoryStream. Обычно каждый раз, когда вы обращаетесь к файлу, вы делаете это с помощью потока. Есть много видов потоков (например, сетевые потоки, файловые потоки и потоки памяти), и все они реализуют один и тот же базовый интерфейс. Если вы уже создаете файл в файловом потоке, а не в строковом или байтовом массиве, то для переключения на MemoryStream потребуется очень мало изменений кода.

По сути, Steam - это просто способ работы с большими объемами данных, при котором вам не нужно или не может загружать все данные в память сразу. Таким образом, вместо того, чтобы читать или записывать весь набор данных в гигантский массив или что-то в этом роде, вы открываете поток, который дает вам эквивалент курсора. Вы можете переместить свое текущее положение в любое место в потоке и читать или писать в него с этой точки.

person Steven Doggart    schedule 04.05.2012