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

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