AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi [TFileStream] Widestring Dateinamen

[TFileStream] Widestring Dateinamen

Ein Thema von necromundo · begonnen am 2. Mär 2009 · letzter Beitrag vom 2. Mär 2009
Antwort Antwort
Seite 1 von 2  1 2   
necromundo

Registriert seit: 31. Jan 2005
26 Beiträge
 
#1

[TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 11:23
Hallo zusammen!

Ich habe hier eine Funktion, die einen Hash für eine Datei berechnen soll und dort wird ein Stream erzeugt wie hier:
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); Nun soll FileName aber ein Widestring sein. solange keine Unicode-Zeichen im dateinamen vorkommen, funktioniert auch alles richtig! aber wenn, kommt ein EFOpenFileError.
Wie kann ich einen TFileStream erzeugen mit einem widestring-dateinnamen??

vg, benny
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.105 Beiträge
 
Delphi 12 Athens
 
#2

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 11:25
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
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;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
necromundo

Registriert seit: 31. Jan 2005
26 Beiträge
 
#3

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 12:30
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?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.105 Beiträge
 
Delphi 12 Athens
 
#4

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 13:11
Zitat von necromundo:
wenn ich eine klasse ableiten will (hast du doch hiermit gemacht, ne)
jupp, hab ich

Zitat von necromundo:
dann kann ich die ja in eine seperate datei schreiben und über uses einbinden, stimmts?
wie sieht so eine klasse.pas komplett aus?
einfach denn Code in eine Unit packen und abspeichern

hier als UnicodeFileStream.pas
Delphi-Quellcode:
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.
aber wie gesagt ... ob alles richtig ist, hab ich jetzt nicht getestet
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
necromundo

Registriert seit: 31. Jan 2005
26 Beiträge
 
#5

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 13:20
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!
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 13:39
Delphi-Quellcode:
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)]);
Sollte MSDN-Library durchsuchenCreateFile fehlschlagen ist der Rückgabewert nicht kleiner null, sondern INVALID_HANDLE_VALUE:
Zitat:
If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.105 Beiträge
 
Delphi 12 Athens
 
#7

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 14:19
ich weiß, aber immerhin ist Integer(INVALID_HANDLE_VALUE) kleiner 0

nja, ich hab das so aus Delphi rauskopiert und nur den Unicode-Teil geändert
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 14:24
Nun ja, ich bevorzuge die Konstanten und halte mich lieber an die Dokumentation.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.105 Beiträge
 
Delphi 12 Athens
 
#9

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 14:26
[add]
hab's mal geändert, aber wie gesagt, so wurde es halt in D7 gemacht
[/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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: [TFileStream] Widestring Dateinamen

  Alt 2. Mär 2009, 14:30
Die hardcodierten Zeichenketten sind natürlich nicht gerade optimal. Aber eine erste Verbesserung wäre es sie als Ressourcenstrings zu deklarieren.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz