AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dateiname auf Gültigkeit prüfen

Ein Thema von himitsu · begonnen am 29. Jul 2005 · letzter Beitrag vom 17. Sep 2005
Thema geschlossen
Seite 1 von 2  1 2      
Benutzerbild von himitsu
himitsu

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

Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 04:32
Zum Beitrag "Dateiname auf Gültigkeit prüfen"

So, und hier ist mal meine Version -.-''

Delphi-Quellcode:
Type TCFNameMode = Set of (
  cnmDOSCompatible, // Tests for file modifier characters ("+", ";", "=" ...).
  cnm8Point3Names, // Tests for short file names (8.3).
  cnmQuoteEnabled); // File name may be included into quotation marks (").

Function CheckFilename(FileName: AnsiString; Mode: TCFNameMode = []; Directory: AnsiString = ''): ByteBool;
  Var i: Integer;
    Quoted: Boolean;
    Buffer: Array[1..MAX_PATH] of AnsiChar;
    P: PAnsiChar;

  Begin
    Result := False;
    If FileName = 'Then Exit;
    Quoted := (cnmQuoteEnabled in Mode) and (FileName[1] = '"') and (FileName[Length(FileName)] = '"');
    If Quoted Then FileName := Copy(FileName, 2, Length(FileName) - 2);
    If (FileName[1] = ' ') and (FileName[Length(FileName)] = ' ') Then Exit;
    For i := Length(FileName) downto 1 do
      If (FileName[i] in [#0..#31, '"', '*', '/', ':', '<', '>', '?', '\', '|']) or
        ((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i] in ['+', ';', '=', '[', ']'])) or
        (((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i] = ' ')) Then Exit;
    If cnm8Point3Names in Mode Then Begin
      i := Pos('.', FileName);
      If i = 0 Then i := Length(FileName) + 1;
      If (i > 9) or (Length(FileName) - i > 3) or (PosEx('.', FileName, i + 1) > 0) Then Exit;
    End;
    If Directory <> 'Then Begin
      If Directory[Length(Directory)] <> '\Then Directory := Directory + '\';
      FileName := Directory + FileName;
    End;
    i := GetFullPathNameA(PAnsiChar(FileName), MAX_PATH, @Buffer, P);
    If (i <= 0) or (i >= MAX_PATH) Then Exit;
    Result := True;
  End;




If not CheckFilename(FileName) Then Error...
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
 
Benutzerbild von Luckie
Luckie

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 05:32
Wo kommt PosEx her? Mein Delphi D6 Personal) kennt es nicht. Grml, nach langem Suchen habe ich wohl was passendes gefunden.

Du hast was vergessen:
Zitat:
The following reserved device names cannot be used as the name of a file: CON, PRN, AUX, CLOCK$, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed by an extension (for example, NUL.tx7).
Und:
Zitat:
Do not end a file or directory name with a trailing space or a period. Although the underlying file system may support such names, the operating system does not.
Das 'test.txt.' und das 'test.txt ' sind bei dir aber ein gültige Dateiname.

Wenn beo Directory der Pfad angegeben werden kann, dann hast du hier auch noch ein Fehler. Denn das als Pfad '\\<\D:\' word auch als gültig mit disem Dateiname 'test.txt' erkannt, obwohl der Pfad ein ungültiges Zeichen enthält.
Michael
Ein Teil meines Codes würde euch verunsichern.
 
Benutzerbild von himitsu
himitsu

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 06:04
Gut, dann werd' ich versuchen es noch etwas zu verbessern.

Allerdings haben die Codes der Anderen mit 'test.txt.' auch ihre Probleme.
Wobei 'test.txt.' als 8.3-Dateiname bei mir nicht durchgehen dürfte ^^


Und das mit dem PosEx vergesse ich manchmal ... da ich es aus 'ner eigenen Codesammlung importiere und weil es in D7 auch nochmal existiert hatte ich es dementsprechend geändert.

eventuell fallen da ja einige unterschiede zum obrigen Code auf ._.
Delphi-Quellcode:
    Function CheckFilename(FileName: AnsiString; Mode: TCFNameMode = []; Directory: AnsiString = ''): ByteBool;
      Var i: Integer;
        Quoted: Boolean;
        Buffer: Array[1..MaxPath] of AnsiChar;
        P: PAnsiChar;

      Begin
        Result := False;
        If FileName = 'Then Exit;
        Quoted := (cnmQuoteEnabled in Mode) and (FileName[1] = '"') and (FileName[_Length(FileName)] = '"');
        If Quoted Then FileName := _Copy(FileName, 2, _Length(FileName) - 2);
        If (FileName[1] = ' ') and (FileName[_Length(FileName)] = ' ') Then Exit;
        For i := _Length(FileName) downto 1 do
          If (FileName[i] in CFForbiddenChars) or
            ((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i] in CFForbiddenCharsDOS)) or
            (((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i] = ' ')) Then Exit;
        If cnm8Point3Names in Mode Then Begin
          i := _Pos('.', FileName);
          If i = 0 Then i := _Length(FileName) + 1;
          If (i > 9) or (_Length(FileName) - i > 3) or (_PosEx('.', FileName, i + 1) > 0) Then Exit;
        End;
        If Directory <> 'Then Begin
          If Directory[_Length(Directory)] <> '\Then _ConcatV(Directory, '\');
          _Swap(FileName, Directory);
          _ConcatV(FileName, Directory);
        End;
        i := GetFullPathNameA(PAnsiChar(FileName), MaxPath, @Buffer, P);
        If (i <= 0) or (i >= MaxPath) Then Exit;
        Result := True;
      End;

Also dann mach ich mich mal wieder an's Werk und mit viel Glück kommt bald (endlich) mal meine UCC raus, wo dieses auch mit drin ist, und dort gibt es dann mit PosEx jedenfalls keine Probleme mehr


[add]
[d]Ach ja, dein zweites Zitat werde ich erstmal ignorieren, da die Leerzeichen bei mir nicht nur am Namensende, sonderen auch am Anfang behandelt werden:[/d]
If (FileName[1] = ' ') and (FileName[_Length(FileName)] = ' ') Then Exit; Und ja, die Pfadangabe kann fehlerhaft sein, da hier nur der Dateiname geprüft wird.
Aber wenn es gewünscht wird, dann kann ich auch diesen noch mit in die Prüfung aufnehmen.
Obwohl ein "total" falscher Pfadname über GetFullPathName ebenfalls mit behandelt und als Fehler quitiert wird.

[add2]
Ich hoffe es funktioniert und gefällt dir vorerst schonmal so etwas besser.
Wie gesagt, das mit dem Pfad werde ich mir auch noch auf Wunsch vornehmen.


Hab versucht die beiden Zitate mit einfließen zu lassen.
(und wie mir aufgefallen ist, sind Leerzeichen am Anfang unter Umständen auch erlaubt)
Delphi-Quellcode:
    Const CFForbiddenChars: Set of AnsiChar = [#0..#31, '"', '*', '/', ':', '<', '>', '?', '\', '|'];
      CFForbiddenCharsDOS: Set of AnsiChar = ['+', ';', '=', '[', ']'];
      CFForbiddenNames: Array[0..6] of AnsiString = ('AUX', 'CLOCK$', 'COM1', 'COM2', 'COM3', 'COM4',
        'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'CON', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6',
        'LPT7', 'LPT8', 'LPT9', 'NUL', 'PRN');

    Function CheckFilename(FileName: AnsiString; Mode: TCFNameMode = []; Directory: AnsiString = ''): ByteBool;
      Var i: Integer;
        Quoted: Boolean;
        Buffer: Array[1..MAX_PATH] of AnsiChar;
        P: PAnsiChar;

      Begin
        Result := False;
        If FileName = 'Then Exit;
        Quoted := (cnmQuoteEnabled in Mode) and (FileName[1] = '"') and (FileName[Length(FileName)] = '"');
        If Quoted Then FileName := Copy(FileName, 2, Length(FileName) - 2);
        If (FileName = '') or
          ((cnmQuoteEnabled in Mode) and (not Quoted) and (FileName[1] = ' ')) or
          ((cnmErrorLeftChar in Mode) and (FileName[Length(FileName)] in [' ', '.'])) Then Exit;
        For i := Length(FileName) downto 1 do
          If (FileName[i] in CFForbiddenChars) or
            ((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i] in CFForbiddenCharsDOS)) or
            (((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i] = ' ')) Then Exit;
        If cnm8Point3Names in Mode Then Begin
          i := Pos('.', FileName);
          If i = 0 Then i := Length(FileName) + 1;
          If (i > 9) or (Length(FileName) - i > 3) or (PosEx('.', FileName, i + 1) > 0) Then Exit;
        End;
        For i := 0 to High(CFForbiddenNames) do If LowerCase(FileName[1]) = CFForbiddenNames[i] Then Exit;
        If Directory <> 'Then Begin
          If Directory[Length(Directory)] <> '\Then Directory := Directory + '\';
          FileName := Directory + FileName;
        End;
        i := GetFullPathNameA(PAnsiChar(FileName), MAX_PATH, @Buffer, P);
        If (i <= 0) or (i >= MAX_PATH) Then Exit;
        Result := True;
      End;

Ach ja, mir ist so, als wenn sich einige Derivate von PosEx in der CodeLib finden ließen ... jedenfalls ist aber im Forum dazu auch noch eine ganze Menge Code zu finden.
Dennoch kommt ihr schonmal eine Ableitung meiner PosEx-Funktion:
Delphi-Quellcode:
  Function _PosEx(Const SubStr, S: AnsiString; Offset: LongInt = 1): LongInt;
    ASM
      PUSH ESI
      PUSH EDI
      PUSH EBX
      TEST &SubStr, &SubStr
      JE @Exit
      TEST &S, &S
      JE @Exit0
      TEST &Offset, &Offset
      JG @POff
      MOV &Offset, 1
      @POff:
      MOV ESI, &SubStr
      MOV EDI, &S
      PUSH EDI
      MOV EAX, &Offset
      DEC EAX
      MOV ECX, [EDI - 4]
      MOV EDX, [ESI - 4]
      DEC EDX
      JS @Fail
      SUB ECX, EAX
      ADD EDI, EAX
      MOV AL, [ESI]
      INC ESI
      SUB ECX, EDX
      JLE @Fail

      @Loop:
      REPNE SCASB
      JNE @Fail
      MOV EBX, ECX
      PUSH ESI
      PUSH EDI
      MOV ECX, EDX
      REPE CMPSB
      POP EDI
      POP ESI
      JE @Found
      MOV ECX, EBX
      JMP @Loop

      @Fail:
      POP EDX

      @Exit0:
      XOR EAX, EAX
      JMP @Exit

      @Found:
      POP EDX
      MOV EAX, EDI
      SUB EAX, EDX

      @Exit:
      POP EBX
      POP EDI
      POP ESI
    End;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
 
Benutzerbild von Luckie
Luckie

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:02
Warum läßt du den Pfad eigentlich gesondert angeben? Schön wäre, wenn man so was: 'c:\dummy\foo\bar\test.txt' zum Überprüfen oder nur 'test.txt' angeben könnte.
Michael
Ein Teil meines Codes würde euch verunsichern.
 
Benutzerbild von himitsu
himitsu

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:16
Zitat von Luckie:
Warum läßt du den Pfad eigentlich gesondert angeben? Schön wäre, wenn man so was: 'c:\dummy\foo\bar\test.txt' zum Überprüfen oder nur 'test.txt' angeben könnte.
Das ist eigentlich 'ne interne Angelegenheit denn so kann man den Dateinamen einzeln prüfen und z.B. verhindern, das er eine Pfadangabe enthält, also dass im Dateinamen keine ":" und/oder "\" enthalten sind.
Außerdem ist dieses eine Kombination derartiger Funktionen aus meinen Programmen und wirde halt so erstellt, dass sie mit diesesn Programmen zusammenarbeitet.


Im Grunde ist "diese" Funktion "nur" da, um einen Dateinamen zu überprüfen.
Und im Endefekt reagieren die anderen TestFunktionen (hier in der DP und anderswo auch) mit einem False, wenn wie eine Pfadangabe (":" oder "\") im Namen entdecken.


Ich könnte aber auch mal über einen weiteren Parameter (Mode) nachdenken, womit man dieses Verhalten ändern könnte, so dass man auch den Dateinamen sammt Verzeichnis übergeben könnte.
(Directory braucht ja nicht angegeben zu werden)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
 
Benutzerbild von Luckie
Luckie

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:23
Nun ja, mit Delphi-Referenz durchsuchenExtractFilename ist es aber kein Problem den Dateinamen vom Pfad zu trennen.
Michael
Ein Teil meines Codes würde euch verunsichern.
 
bigg
(Gast)

n/a Beiträge
 
#7

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:53
Hier wäre meine Variante:

Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Dateiname auf Gültigkeit überprüfen
////////////////////////////////////////////////////////////////////////////////

function IsFileName(FileName: String): Boolean;
const ForbiddenChars = ['"', '<', '>', '|', '*', '/', '\', '?']; // verbotene Zeichen

const ForbiddenNames: Array[0..22] of String[6] = ('AUX', 'NUL', 'PRN' ,'CON', 'CLOCK$', // verbotene Namen
'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9');

var i: Integer;
var p: PChar;
var FileNameU: String;
begin
Result := False;

  if FileName <> 'then // Name darf nicht leer sein
  begin
    i := Length(FileName);

    if FileName[i] <> '.then // letze Zeichen darf kein Punkt sein
    begin
      p := Pointer(FileName);

      repeat if p^ in ForbiddenChars then
        Exit;
        inc(p);
      until p^ = #0;

      if (i < 7) and (i > 2) then
      begin
        FileNameU := UpperCase(FileName);
        for i := 0 to High(ForbiddenNames) do
        begin
          if CompareStr(ForbiddenNames[i], FileNameU) = 0 then
          Exit;
        end;
      end;

    Result := True;
  end;
  end;
end;
//edit: verbotene Namen hinzugefügt
 
Benutzerbild von himitsu
himitsu

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:55
Zitat von Luckie:
Nun ja, mit Delphi-Referenz durchsuchenExtractFilename ist es aber kein Problem den Dateinamen vom Pfad zu trennen.
Im Grunde genommem hast du ja Recht, wobei es dann ein
CheckFilename(ExtractFilename(FileName), [], ExtractPathname(FileName)) auch machen würde.

Aber wenn ich es schon zulasse, das ein Pfad in Dateiname übergeben werden darf, dann will ich auch wenigsten den übergebenen Pfad genau überprüfen...
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
 
Benutzerbild von Luckie
Luckie

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

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 11:58
@bigg: Was ist mit den verbotenen Namen wie COM1, NUL usw.?
Michael
Ein Teil meines Codes würde euch verunsichern.
 
bigg
(Gast)

n/a Beiträge
 
#10

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 12:10
@Luckie:
Die fehlen noch
 
Thema geschlossen
Seite 1 von 2  1 2      


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 22:39 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