![]() |
[TFileStream] Widestring Dateinamen
Hallo zusammen!
Ich habe hier eine Funktion, die einen Hash für eine Datei berechnen soll und dort wird ein Stream erzeugt wie hier:
Delphi-Quellcode:
Nun soll FileName aber ein Widestring sein. solange keine Unicode-Zeichen im dateinamen vorkommen, funktioniert auch alles richtig! aber wenn, kommt ein EFOpenFileError.
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
Wie kann ich einen TFileStream erzeugen mit einem widestring-dateinnamen?? :gruebel: vg, benny |
Re: [TFileStream] Widestring Dateinamen
entweder du steigst auf Delphi2009 um (dort ist es Unicode)
oder du nutzt Fremdkomponente (z.B. von JEDI) oder du leitest dir eine neue Klasse ab und überschreibst dieses .Create. [add] keine Ahnung ob's so richtig ist, aber es kompiliert zumindest :angel2:
Delphi-Quellcode:
Uses RTLConsts;
Type TFileStreamX = Class(TFileStream) Public Constructor Create(Const FileName: WideString; Mode: Word); Overload; Constructor Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Overload; Destructor Destroy; Override; End; Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word); Begin Create(Filename, Mode, 0); End; Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Const AccessMode: Array[0..2] of LongWord = (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); ShareMode: Array[0..4] of LongWord = (0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE); Begin If Mode = fmCreate Then Begin Inherited Create(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)); If FHandle < 0 Then Raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); End Else Begin If ((Mode and 3) <= fmOpenReadWrite) and ((Mode and $F0) <= fmShareDenyNone) Then Begin Inherited Create(CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)); End Else Inherited Create(0); If FHandle < 0 Then Raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end; End; Destructor TFileStreamX.Destroy; Begin If FHandle >= 0 Then FileClose(FHandle); Inherited Destroy; End; |
Re: [TFileStream] Widestring Dateinamen
hey,
danke erstmal für die schnelle antwort! aber ich kann mit dem codeschnipsel leider noch nicht viel anfangen! wenn ich eine klasse ableiten will (hast du doch hiermit gemacht, ne), dann kann ich die ja in eine seperate datei schreiben und über uses einbinden, stimmts? wie sieht so eine klasse.pas komplett aus? |
Re: [TFileStream] Widestring Dateinamen
Zitat:
Zitat:
hier als UnicodeFileStream.pas
Delphi-Quellcode:
aber wie gesagt ... ob alles richtig ist, hab ich jetzt nicht getestet :stupid:
Unit UnicodeFileStream;
Interface Uses RTLConsts, Windows, SysUtils, Classes; Type TFileStreamX = Class(TFileStream) Public Constructor Create(Const FileName: WideString; Mode: Word); Overload; Constructor Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Overload; Destructor Destroy; Override; End; Implementation Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word); Begin Create(Filename, Mode, 0); End; Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Const AccessMode: Array[0..2] of LongWord = (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); ShareMode: Array[0..4] of LongWord = (0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE); Begin If Mode = fmCreate Then Begin Inherited Create(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)); If FHandle < 0 Then Raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); End Else Begin If ((Mode and 3) <= fmOpenReadWrite) and ((Mode and $F0) <= fmShareDenyNone) Then Begin Inherited Create(CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)); End Else Inherited Create(0); If FHandle < 0 Then Raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end; End; Destructor TFileStreamX.Destroy; Begin If FHandle >= 0 Then FileClose(FHandle); Inherited Destroy; End; End. |
Re: [TFileStream] Widestring Dateinamen
ach so, okay, das habe ich jetzt gemacht, aber er findet bei mir die rtlconsts nicht!
gehören die zu einem paket? oder wo kann ich die herbekommen? ich benutze übrigens delphi 5! ;) |
Re: [TFileStream] Widestring Dateinamen
Delphi-Quellcode:
Sollte
Inherited Create(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE,
0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)); If FHandle < 0 Then Raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); ![]() Zitat:
|
Re: [TFileStream] Widestring Dateinamen
ich weiß, aber immerhin ist Integer(INVALID_HANDLE_VALUE) kleiner 0 :stupid:
nja, ich hab das so aus Delphi rauskopiert und nur den Unicode-Teil geändert :angel: |
Re: [TFileStream] Widestring Dateinamen
Nun ja, ich bevorzuge die Konstanten und halte mich lieber an die Dokumentation.
|
Re: [TFileStream] Widestring Dateinamen
[add]
hab's mal geändert, aber wie gesagt, so wurde es halt in D7 gemacht :roll: [/add] RTLConst ist eigentlich von Delphi (zumindestens war die vorhin beim Delphi 7 dabei). Eigentlich ist diese Datei nur drin, da ich die Konstanten bei den Exceptions so gelassen hatte. Weiß zufällig wer, wo in D5 die nötigen Resourcestrings liegen? Nja, erstmal ohne die RTLConsts, aber dafür mit direkt eingebauten Exception-Strings in deutsch.
Delphi-Quellcode:
Unit UnicodeFileStream;
Interface Uses Windows, SysUtils, Classes; Type TFileStreamX = Class(TFileStream) Public Constructor Create(Const FileName: WideString; Mode: Word); Overload; Constructor Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Overload; Destructor Destroy; Override; End; Implementation Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word); Begin Create(Filename, Mode, 0); End; Constructor TFileStreamX.Create(Const FileName: WideString; Mode: Word; Rights: Cardinal); Const AccessMode: Array[0..2] of LongWord = (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); ShareMode: Array[0..4] of LongWord = (0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE); Begin If Mode = fmCreate Then Begin Inherited Create(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)); If FHandle = INVALID_HANDLE_VALUE Then Raise EFCreateError.CreateFmt('Datei "%s" kann nicht erstellt werden. %s', [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); End Else Begin If ((Mode and 3) <= fmOpenReadWrite) and ((Mode and $F0) <= fmShareDenyNone) Then Begin Inherited Create(CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)); End Else Inherited Create(0); If FHandle = INVALID_HANDLE_VALUE Then Raise EFOpenError.CreateFmt('Datei %s kann nicht geöffnet werden. %s', [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end; End; Destructor TFileStreamX.Destroy; Begin If FHandle >= 0 Then FileClose(FHandle); Inherited Destroy; End; End. |
Re: [TFileStream] Widestring Dateinamen
Die hardcodierten Zeichenketten sind natürlich nicht gerade optimal. Aber eine erste Verbesserung wäre es sie als Ressourcenstrings zu deklarieren.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz