Um Dateinamen mir Umlauten mit dem alten FPC 2.x nutzen zu können braucht es ein anderes TFileStream:
Mit diesem TFileStreamUTF8 und TStringListUTF8 funktionieren alle Zeichen im Dateinamen korrekt. Dennoch ist es besser auf FPC3 um zu stellen, damit man besser für die Zukunft gerüstet ist.
Code: Alles auswählen
type
TFileStreamUTF8 = class(THandleStream)
private
FFileName: string;
public
constructor Create(const AFileName: string; Mode: word; Rights: cardinal = 438);
destructor Destroy; override;
property FileName: string read FFilename;
end;
TStringListUTF8 = class(TStringList)
public
constructor Create;
destructor Destroy; override;
procedure SaveToFileUTF8(const FileName: string);
procedure LoadFromFileUTF8(const FileName: string);
function IndexOfText(const sVal: string): integer;
end;
implementation
function FileOpenUTF8Mm(const FileName: string; Mode: integer): THandle;
{$ifdef WINDOWS}
const
AccessMode: array[0..2] of cardinal =
(GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE);
ShareModes: array[0..4] of integer =
(0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE);
{$endif}
begin
{$ifdef WINDOWS}
Result := CreateFileW(PWideChar(UTF8Decode(FileName)),
dword(AccessMode[Mode and 3]), dword(
ShareModes[(Mode and $F0) shr 4]), nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
//if fail api return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1)
{$else}
Result := FileOpen(FileName, Mode);
{$endif}
end;
function FileCreateUTF8Mm(const FileName: string; ShareMode: integer = fmShareExclusive;
Rights: integer = 0): THandle;
{$ifdef WINDOWS}
const
// AccessMode: array[0..2] of Cardinal = (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE);
ShareModes: array[0..4] of integer =
(0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE);
{$endif}
begin
{$ifdef WINDOWS}
Result := CreateFileW(PWideChar(UTF8Decode(FileName)), GENERIC_READ or
GENERIC_WRITE, dword(ShareModes[(ShareMode and $F0) shr 4]),
nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
{$else}
Result := FileCreate(FileName, ShareMode, Rights);
{$endif}
end;
{****************************************************************************}
{* TFileStreamUTF8 *}
{****************************************************************************}
constructor TFileStreamUTF8.Create(const AFileName: string; Mode: word;
Rights: cardinal = 438);
var
hFile: THandle;
begin
FFileName := AFileName;
{$ifdef WINDOWS}
if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) then
begin
if (Mode and fmCreate) = fmCreate then
begin
if FileExists(AFileName) then
DeleteFile(PChar(AFileName));
hFile := FileCreate(AFileName, Mode, Rights);
end
else
hFile := FileOpen(AFileName, Mode);
end
else
{$endif}
begin
if (Mode and fmCreate) = fmCreate then
begin
if FileExistsUTF8(AFileName) then
DeleteFileUTF8(AFileName);
hFile := FileCreateUTF8Mm(AFileName, Mode, Rights);
end
else
hFile := FileOpenUTF8Mm(AFileName, Mode);
end;
if hFile = THandle(-1) then
if (Mode and fmCreate) = fmCreate then
raise EFCreateError.createfmt(SFCreateError, [AFileName])
else
raise EFOpenError.Createfmt(SFOpenError, [AFilename]);
inherited Create(hFile);
end;
destructor TFileStreamUTF8.Destroy;
begin
FileClose(Handle);
inherited Destroy;
end;
{****************************************************************************}
{* TStringListUTF8 *}
{****************************************************************************}
constructor TStringListUTF8.Create;
begin
inherited Create;
end;
destructor TStringListUTF8.Destroy;
begin
inherited Destroy;
end;
procedure TStringListUTF8.SaveToFileUTF8(const FileName: string);
var
TheStream: TFileStreamUTF8;
begin
TheStream := TFileStreamUTF8.Create(FileName, fmCreate);
try
SaveToStream(TheStream);
finally
TheStream.Free;
end;
end;
procedure TStringListUTF8.LoadFromFileUTF8(const FileName: string);
var
TheStream: TFileStreamUTF8;
begin
TheStream := TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(TheStream);
finally
TheStream.Free;
end;
end;
function TStringListUTF8.IndexOfText(const sVal: string): integer;
var
i: integer;
begin
Result := -1;
for i := 0 to Count - 1 do
begin
if SameText(sVal, Self[i]) then
begin
Result := i;
Break;
end;
end;
end;