Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Dateien / Laufwerke (https://www.delphipraxis.net/41-library-dateien-laufwerke/)
-   -   Delphi Dateiname auf Gültigkeit prüfen (https://www.delphipraxis.net/15428-dateiname-auf-gueltigkeit-pruefen.html)

Spezi1980 28. Jan 2004 16:00


Dateiname auf Gültigkeit prüfen
 
Hallo, ich will mal im Sinne von
Zitat:

Die Code-Bibliothek ist um so wertvoller, je mehr Einträge sie zu bieten hat.[...]
mal ein paar Codzeilen aus meiner Sammlung veröffentlichen.

Der folgende code prüft die Richtigkeit eines eingegebenen Dateinamens:

hinter die Uses Clausel folgenden Code einfügen:
Delphi-Quellcode:
const
  ShortForbiddenChars: set of char = [';', '=', '+', '<', '>', '|', '"', '[', ']', ' ', '\', #39, '?'];
  LongForbiddenChar: set of char = ['/', ':', '*','<','>', '|', #39, '\', '?'];
Delphi-Quellcode:
//Schaut, ob ein gültiger Dateiname eingegeben wurde.
function CheckFilename(Filename: string; Win32: Boolean): Boolean;
var
  NameValid: boolean;
  i: Integer;
begin
  NameValid:=true;
  if Win32 then
  begin
    for i := 1 to length(Filename) do
      if Filename[i] in LongForbiddenChars then
        NameValid:=false;
    end else
    begin
      for i := 1 to length(Filename) do
        if Filename[i] in ShortForbiddenChars then
          NameValid:=false;
    end;
  Result:=NameValid;
end;
Über Anregungen und Änderungen freue ich mich immer wieder.

weitere Suchbegriffe: gültig ungültig

[edit=Chakotay1308]'?' hinzugefügt. Mfg, Chakotay1308[/edit]
[edit=Matze]Code formatiert. Mfg, Matze[/edit]
[edit=Dax]Highlighting korrigiert. Mfg, Dax[/edit]
[edit=Matze]Suchbegriff hinzugefügt. Mfg, Matze[/edit]

shmia 10. Mär 2004 09:21

Re: Dateiname auf Gültigkeit prüfen
 
Hier kommt meine verbesserte Version (der Vergleich wird abgebrochen, sobald das 1. ungültige Zeichen erkannt wird):

Delphi-Quellcode:
{******************************************************************
* Philipp Frenzel (Simon Reinhards FAQ)
* ----------------------------
* Name      : FUNCTION CheckFilename(Filename: STRING; Win32: Boolean): Boolean;
* Datum     : 19.02.2004
* Bemerkung : Schaut, ob ein gültiger Dateiname eingegeben wurde.
******************************************************************}
function CheckFilename(const Filename: STRING; Win32: Boolean): Boolean;
const
  {fuer 8.3-Dateinamen im DOS-Format:}
  ShortForbiddenChars: set of char = [';', '=', '+', '<', '>', '|', '"', '[', ']', ' ', '\', #39];
  {fuer lange Dateinamen im Win95-Format:}
  LongForbiddenChars: set of char = ['<', '>', '|', '"', '\'];
var
  i: Integer;
begin
  Result := False;
  if Win32 then
  begin
    for i:=1 to length(Filename) do
      if Filename[i] in LongForbiddenChars then
        Exit;
  end
  else
  begin
    for i:=1 to length(Filename) do
      if Filename[i] in ShortForbiddenChars then
         Exit;
  end;
  Result:=True;
END;
[edit=Chakotay1308]Code-Style. Mfg, Chakotay1308[/edit]
[edit=Dax]Highlighting korrigiert. Mfg, Dax[/edit]

CalganX 17. Sep 2005 13:24

Re: Dateiname auf Gültigkeit prüfen
 
himitsu hat noch folgende Version zusammengebastelt:

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 (").
  cnmErrorLeftChar, // Error on chars to be left out.
  cnmContainPath);  // File name can contain directory. (only if Directory is '')

Const CFForbiddenChars: Set of AnsiChar = [#0..#31, '"', '*', '/', ':', '<', '>', '?', '\', '|'];
  CFForbiddenCharsDOS: Set of AnsiChar = ['+', ';', '=', '[', ']'];
  CFForbiddenNames: Array[0..22] 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, i2, i3: Integer;
    Quoted: Boolean;
    Buffer: Array[1..MAX_PATH] of AnsiChar;
    P: PAnsiChar;
    S: AnsiString;

  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 (cnmContainPath in Mode) and (Directory = '') Then Begin
      Directory := ExtractFileDir(FileName);
      FileName := ExtractFileName(FileName);
    End;
    {check directory}
      i := Length(ExtractFileDrive(FileName)) + 1;
      If Copy(FileName, i, 3) = '..\' Then Inc(i, 3);
      If i - 1 <= Length(FileName) Then
        Repeat
          i2 := PosEx('\', FileName, i);
          If i2 = 0 Then i2 := Length(FileName) + 1;
          If (i = i2) or
            ((cnmQuoteEnabled in Mode) and (not Quoted) and (FileName[i] = ' ')) or
            ((cnmErrorLeftChar in Mode) and (FileName[i2 - 1] in [' ', '.'])) Then Exit;
          For i3 := i2 - 1 downto i do
            If (FileName[i3] in CFForbiddenChars) or
              ((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i3] in CFForbiddenCharsDOS)) or
              (((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i3] = ' ')) Then Exit;
          If cnm8Point3Names in Mode Then Begin
            i3 := PosEx('.', FileName, i);
            If i3 = 0 Then i3 := i2;
            If (i3 - i > 8) or (i2 - i - i3 > 3) Then Exit;
            i3 := PosEx('.', FileName, i3 + 1);
            If (i3 > 0) and (i3 < i2) Then Exit;
          End;
          S := Copy(LowerCase(FileName), i, i2 - i);
          For i3 := High(CFForbiddenNames) downto 0 do If S = CFForbiddenNames[i3] Then Exit;
          If i2 > Length(FileName) Then Break;
          i := i2;
        Until False;
    {check fileName}
    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;
    S := LowerCase(FileName);
    For i := High(CFForbiddenNames) downto 0 do If S = 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;
Unter Verwendung von folgender PosEx-Variante(falls die Delphi-Version, die ihr benutzt, kein PosEx mitbringen sollte):
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;
[edit=Dax]Highlighting korrigiert. Mfg, Dax[/edit]

CalganX 17. Sep 2005 13:25

Re: Dateiname auf Gültigkeit prüfen
 
Und bigg hat noch zusätzlich folgende Version im Angebot:

Delphi-Quellcode:
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=Dax]Highlighting korrigiert. Mfg, Dax[/edit]

Matze 14. Feb 2007 08:36

Re: Dateiname auf Gültigkeit prüfen
 
himitsu weist auf die Funktion CheckNameLegalDOS8Dot3 hin, die es seit dem Service Pack 1 von Windows XP gibt:


Delphi-Quellcode:
Function CheckNameLegalDOS8Dot3(Name, OemName: PChar; OemNameSize: LongWord;
  NameContainsSpaces, NameLegal: PLongBool): LongBool; StdCall;
  External 'Kernel32.dll' Name 'CheckNameLegalDOS8Dot3';
Zitat:

Zitat von PSDK
Requirements
Client: Requires Windows XP SP1.
Server: Requires Windows Server 2003.

Beispiele:

Delphi-Quellcode:
If CheckNameLegalDOS8Dot3(PChar(Name), nil, 0, nil, nil) then
  // file name is valide

Var OEMName: Array[1..12] of Char;
  NameContainsSpaces, NameLegal: LongBool;

If CheckNameLegalDOS8Dot3(PChar(Name), PChar(OEMName), Length(OEMName), @NameContainsSpaces, @NameLegal)
  and not NameContainsSpaces and NameLegal then
  // file name is valide
  // OEMName return the OEM name for this file
[edit=Luckie] Mfg, Luckie[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:12 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