![]() |
Dateiname auf Gültigkeit prüfen
Zum Beitrag "
![]() 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... |
Re: Dateiname auf Gültigkeit prüfen
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:
Zitat:
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. |
Re: Dateiname auf Gültigkeit prüfen
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]
Delphi-Quellcode:
Und ja, die Pfadangabe kann fehlerhaft sein, da hier nur der Dateiname geprüft wird.
If (FileName[1] = ' ') and (FileName[_Length(FileName)] = ' ') Then Exit;
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; |
Re: Dateiname auf Gültigkeit prüfen
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.
|
Re: Dateiname auf Gültigkeit prüfen
Zitat:
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) |
Re: Dateiname auf Gültigkeit prüfen
Nun ja, mit
![]() |
Re: Dateiname auf Gültigkeit prüfen
Hier wäre meine Variante:
Delphi-Quellcode:
//edit: verbotene Namen hinzugefügt
////////////////////////////////////////////////////////////////////////////////
// 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; |
Re: Dateiname auf Gültigkeit prüfen
Zitat:
Delphi-Quellcode:
auch machen würde.
CheckFilename(ExtractFilename(FileName), [], ExtractPathname(FileName))
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... |
Re: Dateiname auf Gültigkeit prüfen
@bigg: Was ist mit den verbotenen Namen wie COM1, NUL usw.?
|
Re: Dateiname auf Gültigkeit prüfen
@Luckie:
Die fehlen noch :coder: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:39 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