Potřebujete otevřít soubor v Unicode v Delphi 7. Zní to možná jednoduše nicméně. Windows chápou Unicode jako UTF-16, ale NIX systémy jako UTF-8 což už je první zádrhel. Delphi 7 mají jako první náznak Multibyte datový typ Widestring. Takže to můžeme použít asi nějak takto.
function TfrmMain.LoadFileWide(tmpfileName:String):string;
var
tmpStream : TFilestream;
SS: TStringStream;
character: WideChar;
doc : TextFile;
delka,precteno:integer;
tmpString,fullString : string;
c: record
case boolean of
false: (a: array[0..1] of AnsiChar);
true : (w: WideChar);
end;
begin
tmpStream := TFileStream.Create(tmpfilename,fmShareDenyNone);
tmpStream.Seek(0,soFromBeginning);
Result := '';
delka := tmpStream.Size;
precteno := 0;
while precteno<delka do
begin
tmpStream.Read(c.a[0],1);
tmpStream.Read(c.a[1],1);
fullString := fullString + c.w;
inc(precteno,2);
end;
result := fullString;
end;
Tím sice přečteme Unicode file, ale taky nám může přijít soubor v jiném kódování a ten asi přes multibyte prohnat nechceme. Tak si přečteme jeho info a rozhodneme se co s tím.
function UTF16FileBOM(const FileName: string): boolean;
var
txt: file;
bytes: array[0..1] of byte;
amt: integer;
begin
FileMode := fmOpenRead;
AssignFile(txt, FileName);
Reset(txt, 1);
try
BlockRead(txt, bytes, 2, amt);
result := (amt=2) and (bytes[0] = $FF) and (bytes[1] = $FE);
finally
CloseFile(txt);
end;
end;
Takže si ještě přidáme detekci kódování a pak soubor zpracujeme.
if UTF16FileBOM(FilenameEdit1.FileName) then
begin
tmpString := LoadFileWide(FilenameEdit1.FileName);
SaveFileWide(FilenameEdit1.FileName+'.tmp',copy(tmpString,2,length(tmpString)-2));
CSVMemo.LoadFromFile(FilenameEdit1.FileName+'.tmp');
DeleteFile(FilenameEdit1.FileName+'.tmp');
end
else
CSVMemo.LoadFromFile(FilenameEdit1.FileName);
Celý příklad je vypreparovaný z funkčního řešení, ale trošku upraven pro zobecnění.