未测试 Delphi读写UTF-8、Unicode格式文本文件

// UTF-8文件写入函数
procedure SaveUTFFile(const FileName: string; S: string; WriteHeader: Boolean = True);
var
MemStream: TMemoryStream;
HeaderStr: String;
begin
if S = '' then Exit; 

MemStream := TMemoryStream.Create;
try
if WriteHeader then
begin
HeaderStr:=#$EF#$BB#$BF;
MemStream.Write(HeaderStr[1], 3);
end; S := AnsiToUtf8(S);
MemStream.Write(S[1], Length(S));
MemStream.Position := 0; MemStream.SaveToFile(FileName);
finally
MemStream.Free;
end;
end;

// UtF-8文件读取函数
function LoadUTFFile(const FileName: string; ReadHeader: Boolean = True): string;
var
MemStream: TMemoryStream;
S, HeaderStr:string;
begin
Result:='';
if not FileExists(FileName) then Exit;
MemStream := TMemoryStream.Create;
try
MemStream.LoadFromFile(FileName);
if ReadHeader then
begin
SetLength(HeaderStr, 3);
MemStream.Read(HeaderStr[1], 3); if HeaderStr = #$EF#$BB#$BF then
begin
SetLength(S, MemStream.Size - 3);
MemStream.Read(S[1], MemStream.Size - 3);
end;
end else
begin
SetLength(S, MemStream.Size);
MemStream.Read(S[1], MemStream.Size);
end;

Result := Utf8ToAnsi(S);
finally
MemStream.Free;
end;
end;

// Unicode文件写入函数
procedure SaveUnicodeFile(const FileName:string; const S: string; WriteHeader: Boolean = True);
var
MemStream: TMemoryStream;
HeaderStr: string;
WStr: WideString;
begin
if S = '' then exit;
MemStream := TMemoryStream.Create;
try
if WriteHeader then
begin
HeaderStr := #$FF#$FE;
MemStream.Write(HeaderStr[1], 2);
end;

WStr := WideString(S);
MemStream.Write(WStr[1], Length(WStr)*2);
MemStream.Position := 0;
MemStream.SaveToFile(FileName);
finally
MemStream.Free;
end;
end;

// Unicode文件读取函数
function LoadUnicodeFile(const FileName: string; ReadHeader: Boolean = True): string;
var
MemStream: TMemoryStream;
FlagStr: String;
WStr: WideString;
begin
Result := '';
if not FileExists(FileName) then Exit;MemStream := TMemoryStream.Create;
try
MemStream.LoadFromFile(FileName); if ReadHeader then
begin
SetLength(FlagStr, 2);
MemStream.Read(FlagStr[1], 2);

if FlagStr = #$FF#$FE then
begin
SetLength(WStr, (MemStream.Size-2) div 2);
MemStream.Read(WStr[1], MemStream.Size - 2);
end;
end else
begin
SetLength(WStr, MemStream.Size div 2);
MemStream.Read(WStr[1], MemStream.Size);
end;

Result := AnsiString(WStr);
finally
MemStream.Free;
end;
end;


//保存文件
procedure savetofile(const FileName:string; const S: string);
var
F: TextFile;
begin
AssignFile(F, FileName); // 将文件与F变量建立连接,后面可以使用F变量对文件进行操作。
Rewrite(F); // 以追加的方式打开文件
Writeln(F, S); // 将S变量中的内容追加到文本尾后。
CloseFile(F); // 关闭文件
end;
type
  TTextFormat=(tfAnsi,tfUnicode,tfUnicodeBigEndian,tfUtf8);
const
  TextFormatFlag:array[tfAnsi..tfUtf8] of word=($0000,$FFFE,$FEFF,$EFBB); 
 
function WordLoHiExchange(w:Word):Word;register;
asm
  XCHG AL, AH
end;
 
{ TextFormat返回文本编码类型,sText未经处理的文本 }
procedure ReadTextFile(const FileName: string;
  var TextFormat: TTextFormat; var sText:string);
var
  w:Word;
  b:Byte;
begin
  with TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone) do
  try
    Read(w,2);
    w:=WordLoHiExchange(w);//因为是以Word数据类型读取,故高低字节互换
    if w = TextFormatFlag[tfUnicode] then
      TextFormat:= tfUnicode
    else if w = TextFormatFlag[tfUnicodeBigEndian] then
      TextFormat:= tfUnicodeBigEndian
    else if w = TextFormatFlag[tfUtf8] then
    begin
      Read(b,1);//这里要注意一下,UFT-8必须要跳过三个字节。
      TextFormat:=tfUtf8;
    end else
    begin
      TextFormat:=tfANSI;
      Position:=0;
    end;
    SetLength(sText,Size-Position);
    ReadBuffer(sText[1],Size-Position);
  finally
    Free;
  end;
end;