Stream (.NET) для работы с лучшими практиками - PullRequest
4 голосов
/ 26 февраля 2009

Вопрос озаглавлен словом «Поток», потому что приведенный ниже вопрос является конкретным примером более общего сомнения, который у меня есть в отношении потоков:

У меня есть проблема, которая принимает два решения, и я хочу знать лучшее:

  1. Я загружаю файл, сохраняю его на диск (2 минуты), читаю и записываю содержимое в БД (+ 2 минуты).
  2. Я загружаю файл и записываю содержимое прямо в БД (3 мин).

Если запись в БД не удастся, мне придется загружать снова во втором случае, но не в первом.

Что лучше? Что бы вы использовали?

Ответы [ 8 ]

3 голосов
/ 26 февраля 2009

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

Или, может быть, Вариант 3, предложенный Максом Шмелингом , сохранить в файловую систему одновременно с записью в базу данных.

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

2 голосов
/ 26 февраля 2009

Подробно ответ Джекке:

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

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

2 голосов
/ 26 февраля 2009

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

Перейти с вариантом № 2.

1 голос
/ 26 мая 2010

Я бы пошел на пока еще не упомянутый (за исключением комментариев) вариант, упомянутый в теме моего блога о blobstreams : настроить конвейер обработки потоков, которые заботятся о загрузка и интерпретация нужного вам файла. Затем используйте код для чтения интерпретированных записей из этого составного потока и выполните необходимые вставки / обновления в вашей базе данных в рамках одной транзакции (для файла / для каждой записи в соответствии с вашими функциональными требованиями).

Этот сценарий - то, где Stream классы на основе превосходят. Это будет означать, что во время обработки у вас никогда не будет целого файла ни на диске, ни в памяти одновременно. Как вы упоминали, загрузка файла занимает несколько минут, он может быть большим. Может ли ваша система занять промежуточное хранилище полного файла (может быть, несколько раз: память и на диске)? Даже если несколько файлов обрабатываются одновременно?

Кроме того, если вы обнаружите на практике, что цепочка недостаточно надежна для вас, и вы хотели бы иметь возможность временно сохранить загруженный файл на диск и действительно хотите затем повторить его обработку, не загружая его опять же, это легко. Все, что нужно, - это дополнительный Stream в конвейере, который будет проверять, находится ли нужный файл уже в вашем кэше «уже загруженных файлов» (в какой-то папке, в изолированном хранилище и т. Д.) И возвращать байты в этом, а не фактически зацикливание загрузки Stream в ваш конвейер обработки.

1 голос
/ 26 февраля 2009

Я бы выбрал вариант 3. Сохраните его на диск и сохраните URI в базе данных. Я никогда не был фанатом хранения файлов в базе данных.

1 голос
/ 26 февраля 2009

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

1 голос
/ 26 февраля 2009

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

РЕДАКТИРОВАТЬ: в оригинальном сообщении автор описывает запись непосредственно в базу данных как двухэтапный процесс, который я предполагаю равным 1. Загрузите файл в переменную, 2. Потоковое содержимое переменной в БД. Если он использует потоковую передачу напрямую в БД в варианте 2, то я согласен, что это лучший путь.

1 голос
/ 26 февраля 2009

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

Если у вас нет веских причин хранить копию файла в файловой системе, в большинстве случаев я бы использовал # 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...