Задача: Нужно сохранить данные, которые хранятся в 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