Какой самый быстрый способ записать сотни файлов на диск с помощью C#?

Моя программа должна записывать на диск сотни файлов, полученных внешними ресурсами (сетью), каждый файл представляет собой простой документ, который я сейчас храню с именем GUID в определенной папке, но создание сотен файлов, запись, закрытие - это долго процесс.

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

Во-первых, я создаю 2 файла, один из них похож на таблицу распределения, а второй — это огромный файл, в котором хранится все содержимое моих документов. Но чтение из этого файла было бы кошмаром; возможно, может помочь метод файлов с отображением памяти. Может ли работа с 30 ГБ или более создать проблему?

Изменить: Как быстрее всего сохранить 1000 текстовых файлов на диске? (операция записи выполняется часто)


person Ehsan    schedule 10.01.2011    source источник
comment
Пожалуйста, предоставьте дополнительную информацию - каковы обычные схемы доступа к этим файлам? Написать один раз прочитать много? Писать много? Ожидается ли изменение размеров файлов?   -  person Oded    schedule 10.01.2011
comment
Насколько велики обычно эти файлы?   -  person Tim Lloyd    schedule 10.01.2011
comment
Вы не можете ускорить дисковый ввод-вывод с помощью кода. Возьмите более быстрый диск. Как те, которые вы найдете на сервере dbase.   -  person Hans Passant    schedule 10.01.2011
comment
Наличие сотен дисководов, подключенных к вашему компьютеру. :-)   -  person Gilbert Le Blanc    schedule 10.01.2011
comment
каждый файл имеет средний размер 5 КБ, но их много, например, мне нужно написать 1000 таких файлов. и тяжелые операции ввода-вывода влияют на другие службы моего сервера. Я хочу найти решение для сокращения операций ввода-вывода и, следовательно, времени отклика других моих служб плюс (эти операции записи выполняются в области транзакций, поэтому накладные расходы велики)   -  person Ehsan    schedule 11.01.2011


Ответы (3)


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

Если вы планируете часто изменять эти документы, вы можете рассмотреть возможность использования встроенной базы данных для управления твердым файлом (Firebird). хороший, у которого нет ограничений по размеру). Таким образом, вам не нужно самостоятельно управлять ростом и организацией файлов (что может усложниться, когда вы начнете изменять файлы внутри сплошного файла). Это также поможет с вопросами параллельного доступа (чтение/запись), если вы используете отдельный сервис/процесс для управления базой данных и связи с ней. Новая версия Firebird (2.5) поддерживает многопроцессный доступ к базе данных даже при использовании встроенного сервера. Таким образом, вы можете иметь множественный доступ к хранилищу файлов без необходимости запуска сервера базы данных.

person Garo Yeriazarian    schedule 10.01.2011

Первое, что вы должны сделать, это профилировать ваше приложение. В частности, вы хотите получить счетчики длины очереди диска. Длина вашей очереди не должна превышать длину очереди более чем в 1,5–2 раза. количество дисковых шпинделей у вас есть.

Например, если у вас однодисковая система, то длина очереди не должна превышать 2. Если у вас RAID-массив с 3 дисками, она должна быть больше 6.

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

Если производительность записи критична, то можно распределить хранилище по нескольким дискам. Конечно, вам придется принять это во внимание для любого приложения, которому необходимо прочитать эту информацию. И вам все равно придется покупать быстрые диски.

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

person NotMe    schedule 10.01.2011

Как насчет использования для этого ThreadPool?

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

person Uwe Keim    schedule 10.01.2011
comment
@Uwe Диски не могут поддерживать одновременные операции записи, у них есть только один набор головок. Добавление потоков может привести к хуже производительности. - person Tim Lloyd; 10.01.2011
comment
Так что было бы лучше поставить его в очередь и использовать сериализованный центральный поток для записи каждого файла за раз? - person Uwe Keim; 10.01.2011
comment
Да, обычно рекомендуется поставить в очередь и делегировать задачу другому выделенному потоку. Если бы вы поставили его в очередь в пул потоков, вы могли бы столкнуться с классической проблемой, когда вы перегружаете диск, и поэтому рабочие элементы выполняются все дольше и дольше. В конце концов пул потоков начинает увеличивать количество потоков, что приводит к положительной обратной связи, и все выходит из-под контроля. - person Tim Lloyd; 10.01.2011
comment
Дополнительный вопрос, просто из любопытства: я использую SSD на своем ПК. Это относится и к твердотельным накопителям, или только к механическим жестким дискам? - person Uwe Keim; 10.01.2011
comment
Я знаю, что это проблема с жесткими дисками, я подозреваю, что с более быстрыми твердотельными накопителями проблем будет гораздо меньше, но я недостаточно знаю о твердотельных накопителях, чтобы ответить на них. Я подозреваю, что они также не разрешают параллельные операции. - person Tim Lloyd; 10.01.2011
comment
Многопоточность должна быть быстрее при записи на диск. Из-за буфера, который у него есть. Пока диск записывает, другой поток может писать в буфер. Количество потоков нужно откалибровать (не тривиальная задача). Но, как сказал Чибасити, лучше всего, если всю работу по написанию сделает гусеница. - person Cédric Guillemette; 10.01.2011
comment
@Uwe Keim: Что касается твердотельных накопителей, проблема действительно связана с пропускной способностью, а не с какой-либо физической конструкцией диска. ЦП имеет только одно соединение с диском (через кабель SATA), поэтому максимальная скорость записи на диск ограничивается на верхнем конце размером канала SATA или скоростью записи диска. Запись в несколько потоков просто чередует данные в соединении SATA. На SSD было бы меньше отходов из-за отсутствия движущихся головок, но, поскольку вы все еще ограничены пропускной способностью, вам будет лучше записывать последовательно, поскольку это снижает нагрузку на ЦП. - person Simon P Stevens; 10.01.2011
comment
@Cedrik: я не согласен. Неважно, есть ли на диске аппаратный буфер, ЦП может намного опережать производительность любого диска (даже SSD), поэтому, просто запустив один поток, вы можете продолжать заполнять буфер, пока диск пишу. Ваш единственный поток не блокируется, пока буфер не заполнится. - person Simon P Stevens; 10.01.2011