Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Работа с большими файлами в SQL Server Express с использованием FileStream и Delphi: решения проблемы "Out of memory"

Delphi , Базы данных , SQL

Вопрос, поднятый пользователем, касается проблемы, возникающей при работе с большими файлами в SQL Server Express с использованием FileStream. При попытке вставки 600 МБ файла в базу данных через Delphi и компоненты SDAC возникает ошибка "Out of memory". Пользователь использовал компонент TMSQuery для вставки файла в таблицу, что приводило к значительному увеличению использования памяти в менеджере памяти Delphi.

Описание проблемы

Пользователь столкнулся с проблемой при работе с большими файлами в конфигурации SQL Server Express для хранения данных FileStream. При вставке файлов из папки в базу данных в цикле, все шло гладко до попытки вставки файла размером 600 МБ. В этот момент наблюдалось значительное увеличение использования памяти и возникала ошибка. Несмотря на то, что общий размер базы данных был менее 1 ГБ, а общее количество документов составляло 8 ГБ, пользователь ожидал, что ограничение в 10 ГБ для SQL Server Express R2 не должно было стать проблемой.

Анализ контекста

Обновление вопроса указывает на то, что проблема, вероятно, связана с ограничениями менеджера памяти Delphi. При использовании компонентов SDAC для вставки файла в таблицу с полями PK (ID_DOC_FILE) и varbinary(max) (DOCUMENT) через процедуру UploadBigFile, менеджер памяти Delphi не справлялся с обработкой файлов размером более 500 МБ. Команда SDAC сообщила, что это ограничение связано именно с менеджером памяти Delphi.

Подтвержденный ответ

Исследование показало, что проблема не полностью в менеджере памяти, а в том, как Delphi обрабатывает большие объемы данных. Delphi использует один Variant для хранения данных, загружаемых в параметр, и при этом создает копии этого Variant, что приводит к значительному увеличению использования памяти. Особенно это критично для 32-битных приложений, которые не работают в режиме "3G".

Альтернативный ответ и предложенное решение

Одно из предложенных решений заключается в разбиении файла на меньшие части, которые можно обрабатывать по отдельности. Для этого можно настроить таблицу базы данных с тремя полями: ID_DOCUMENT, SEQUENCE, DOCUMENT, а также установить составной первичный ключ (ID_DOCUMENT, SEQUENCE). Затем использовать процедуру UploadBigFile, которая будет читать файл по частям и вставлять их в базу данных.

procedure UploadBigFile(id_doc: Integer; sFilePath: String);
var
  FS: TFileStream;
  MS: TMemoryStream;
  AvailableSize, ReadNow: Int64;
  Sequence: Integer;
const
  MaxPerSequence = 10 * 1024 * 1024; // 10 Mb
begin
  FS := TFileStream.Create(sFilePath, fmOpenRead);
  try
    AvailableSize := FS.Size;
    Sequence := 0;
    while AvailableSize > 0 do
    begin
      if AvailableSize > MaxPerSequence then
      begin
        ReadNow := MaxPerSequence;
        Dec(AvailableSize, MaxPerSequence);
      end
      else
      begin
        ReadNow := AvailableSize;
        AvailableSize := 0;
      end;
      Inc(Sequence); // Подготовка последовательности; первая последовательность в БД будет "1"
      MS := TMemoryStream.Create;
      try
        MS.CopyFrom(FS, ReadNow);
        sqlInsertDoc.ParamByName('ID_DOC_FILE').AsInteger := id_doc;
        sqlInsertDoc.ParamByName('SEQUENCE').AsInteger := Sequence;
        sqlInsertDoc.ParamByName('DOCUMENT').LoadFromStream(MS, ftblob);
        sqlInsertDoc.Execute();
      finally
        MS.Free;
      end;
    end;
  finally
    FS.Free;
  end;
  sqlInsertDoc.Close;
end;

Заключение

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

Создано по материалам из источника по ссылке.

Вопрос связан с решением проблемы 'Out of memory' при работе с большими файлами в SQL Server Express с использованием FileStream и Delphi, с предложенным решением разбиения файлов на части для уменьшения использования памяти.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: SQL ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 13:45:32/0.0051898956298828/1