Сохранение содержимого TWebBrowser в базу данных через TMemoryStream в Delphi XE7
Проблема сохранения HTML из TWebBrowser
При работе с компонентом TWebBrowser в Delphi XE7 разработчики часто сталкиваются с проблемой сохранения содержимого веб-страницы в базу данных. Основная сложность возникает при попытке записать HTML-контент в BLOB-поле после сохранения во временный файл, так как файл может оставаться заблокированным другим процессом.
Оригинальный код для сохранения выглядит так:
function WB_SaveAs_HTML(WB:TWebBrowser; const FileName : string):boolean;
var
PersistStream: IPersistStreamInit;
Stream: IStream;
FileStream: TFileStream;
begin
result:=true;
if not Assigned(WB.Document) then
begin
result:=false;
Exit;
end;
PersistStream := WB.Document as IPersistStreamInit;
FileStream := TFileStream.Create(FileName, fmCreate or fmShareDenyNone);
try
Stream := TStreamAdapter.Create(FileStream, soReference) as IStream;
if Failed(PersistStream.Save(Stream, True)) then
result:=false
finally
FileStream.Free;
end;
(WebBrowser1.Document as IHTMLDocument2).designMode := 'off';
end;
При последующей загрузке в базу данных возникает ошибка:
EFOpen Error cannot open file ... The process cannot access the file "<Path>" because it is being used by another process
Решение с использованием TMemoryStream
Более эффективное решение - использовать TMemoryStream для сохранения HTML непосредственно в память, минуя промежуточный файл:
Вариант 1: Использование CreateBlobStream
function WB_SaveAs_HTML(WB: TWebBrowser; AStream: TStream): Boolean;
var
PersistStream: IPersistStreamInit;
SaveStream: IStream;
begin
Result := False;
if not Assigned(WB.Document) then Exit;
PersistStream := WB.Document as IPersistStreamInit;
SaveStream := TStreamAdapter.Create(AStream, soReference) as IStream;
Result := Succeeded(PersistStream.Save(SaveStream, True));
(WB.Document as IHTMLDocument2).designMode := 'off';
end;
Пример использования:
var
Field: TField;
Stream: TStream;
begin
Field := Query.FindField('content');
Stream := Field.DataSet.CreateBlobStream(Field, bmWrite);
try
WB_SaveAs_HTML(WebBrowser1, Stream);
finally
Stream.Free;
end;
end;
Вариант 2: Прямая работа с TMemoryStream
Альтернативный подход с возвратом потока из функции:
function WB_SaveAs_HTML(WB: TWebBrowser; out Output: TStream): Boolean;
var
PersistStream: IPersistStreamInit;
Stream: IStream;
begin
if not Assigned(WB.Document) then Exit(False);
PersistStream := WB.Document as IPersistStreamInit;
Output := TMemoryStream.Create;
try
Stream := TStreamAdapter.Create(Output, soReference) as IStream;
Result := not Failed(PersistStream.Save(Stream, True));
except
Result := False;
end;
if Result then
Output.Position := 0
else
FreeAndNil(Output);
(WB.Document as IHTMLDocument2).designMode := 'off';
end;
Пример использования:
var
Stream: TStream;
begin
if WB_SaveAs_HTML(WebBrowser1, Stream) then
try
(Query.FindField('content') as TBlobField).LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
Преимущества использования TMemoryStream
Исключение проблем с блокировкой файлов - данные сохраняются непосредственно в память, без создания временных файлов
Увеличение производительности - работа с памятью быстрее, чем с файловой системой
Более чистый код - меньше операций ввода-вывода, проще обработка ошибок
Безопасность - отсутствие временных файлов исключает возможность их перехвата или повреждения
Дополнительные рекомендации
Всегда проверяйте успешность выполнения операций с интерфейсами COM
Устанавливайте позицию потока в 0 перед чтением (Position := 0)
Используйте try-finally блоки для освобождения ресурсов
Рассмотрите возможность добавления обработки ошибок для случаев, когда документ не загружен или поврежден
Это решение эффективно обходит проблему блокировки файлов и предоставляет более надежный способ сохранения HTML-контента из TWebBrowser непосредственно в базу данных.
Решения для сохранения HTML-контента из TWebBrowser в базу данных через TMemoryStream в Delphi XE7, исключая проблемы с блокировкой файлов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.