Delphi — TStringList with UTF8 without BOM

Задача: Нужно сохранить данные, которые хранятся в TStringList в UTF8 без BOM (Byte Order Mark)
Инструментарий: Delphi 2010, Delphi 10S
Решение: У нас есть несколько вариантов решения данной проблемы. Все зависит от версии Delphi, которую вы используете.
В более новых версиях Delphi (начиная с XE2) появилось свойство WriteBOM, которое указывает записывать BOM заголовок в файл при вызове SaveToFile/SaveToStream или нет.

Пример:

var
List: TStringList;
Encoding: TEncoding;
begin
List := TStringList.Create;
try
Encoding := TUTF8Encoding.Create;
//указываем записывать BOM или нет.
List.WriteBOM := false;
List.Add('text');
List.SaveToFile('C:\text1.txt', Encoding );
finally
FreeAndNil(List);
FreeAndNil(Encoding);
end;

Другой метод, подойдет для более младших версий Delphi. Можно создать свой класс-наследник от TUTF8Encoding и переопределить метод GetPreamble.

Пример:

type
TUTF8EncodingNoBOM = class(TUTF8Encoding)
public
function GetPreamble: TBytes; override;
end;

function TUTF8EncodingNoBOM.GetPreamble: TBytes;
begin
SetLength(Result, 0);
end;

var
List: TStringList;
Encoding: TEncoding;
begin
List := TStringList.Create;
try
// создаем экземпляр своего класса
Encoding := TUTF8EncodingNoBOM.Create;
List.Add(Text);
List.SaveToFile(FileName, Encoding);
finally
FreeAndNil(List);
FreeAndNil(Encoding);
end;
end;

Если сравнить содержимое текстовых файлов с BOM и без него в любом Hex редакторе — мы увидим следующее:

Файл с BOM:

EF BB BF 74 65 78 74 0D 0A

Файл без BOM:

74 65 78 74 0D 0A

Исходники на GitHub

Добавить комментарий