Is there any way to check the file name?

I thought it should be somewhere in RTL, but I looked and I can not find it.

function IsValidFilename(filename: string): boolean; //returns True if it would be possible to create or open a file with //this name, without modifying the current directory structure 

In other words, it must point to an existing folder on a valid local or network drive and not contain any invalid characters. Do we have something like that? (Bonus points if he checks the user's current access rights to make sure that you can get to the specified folder.)

+7
filenames delphi
source share
10 answers

So this question is a bit old, but just in case you are looking: With XE and newer you can use the TPath class in System.IOUtils .

 Result := TPath.HasValidFileNameChars(AFileName, UseWildcards); 
+11
source share

As far as I know, there is no RTL or Windows API function for checking the file name, so you should write your own function following the Windows file naming conventions :

The following fundamental rules allow applications to create and process valid names for files and directories regardless of the file system:

  • Use a period to branch the base file name from the extension in the directory or file name.
  • Use backslash () to separate path components. A backslash separates the file name from the path to it and one directory name from another directory name in the path. You cannot use a backslash in a name for an actual file or directory, because it is a reserved character that separates the names into components.
  • If necessary, use a backslash as part of the volume names, for example, "C: \" in "C: \ path \ file" or "\ server \ share" in "\ server \ share \ path \ file" for Universal Naming Convention (UNC). For more information about UNC names, see "Limiting the Maximum Path Length".
  • Do not assume case sensitivity. For example, suppose the names OSCAR, Oscar, and oscar are the same, although some file systems (such as the POSIX-compatible file system) may consider them different. Note that NTFS supports POSIX semantics for case sensitivity, but this is not the default behavior. See CreateFile for more information.
  • Volume designations (drive letters) are also case sensitive. For example, "D: \" and "d: \" refer to the same thing.
  • Use any character in the current code page for the name, including Unicode characters and characters in the extended character set (128–255), except for the following:

    • The following reserved characters:
      • <(less than)
      • > (more than)
      • : (colon)
      • "(double quote)
      • /(slash)
      • \ (backslash)
      • | (vertical bar or pipe)
      • ? (question mark)
      • * (asterisk)
    • The integer value is zero, sometimes called the ASCII NUL character.
    • Characters whose integer representations range from 1 to 31, with the exception of alternative streams where these characters are allowed. For more information about file streams, see File Streams.
    • Any other character that the target file system does not allow.
  • Use a period as a directory component in a path to represent the current directory, for example, ". \ Temp.txt". See Ways for more information.
  • Use two consecutive periods (..) as a directory component in the path to represent the parent of the current directory, for example ".. \ temp.txt". See Ways for more information.
  • Do not use the following reserved device names for the file name:

    CON, PRN, AUX, 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 immediately by the extension; for example, NUL.txt is not recommended. See Namespaces for more information.

  • Do not end the file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface do not. However, it is permissible to specify a period as the first character of a name. For example, ".temp".

You can check out this C ++ article File Name Checker for a complete example of a function for checking Windows file names.

+10
source share

Is it too rude, Mason?

 function CanCreateFile(const FileName: string): Boolean; var H: THandle; begin H := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0); Result := H <> INVALID_HANDLE_VALUE; DeleteFile(FileName); end; 
+5
source share

I don’t have access to the Delphi compiler right now, but you can try

 function IsValidFilename(const FileName: string): boolean; begin result := DirectoryExists(ExtractFilePath(FileName)) and TPath.HasValidFileNameChars(ExtractFileName(FileName), false); end; 
+4
source share

To find out if it exists, use DirectoryExists() and FileExists() . To find out if you can create / edit a file, use FileOpen() with ReadWrite and see if it succeeds.

+3
source share

try this code (taken from delphi faq )

 const { for short 8.3 file names } ShortForbiddenChars : set of Char = [';', '=', '+', '<', '>', '|', '"', '[', ']', '\', '/', '''']; { for long file names } LongForbiddenChars : set of Char = ['<', '>', '|', '"', '\', '/', ':', '*', '?']; function TestFilename(Filename: String; islong: Boolean) : Boolean; var I: integer; begin Result := Filename <> ''; if islong then begin for I := 1 to Length(Filename) do Result := Result and not (Filename[I] in LongForbiddenChars); end else begin for I := 1 to Length(Filename) do Result := Result and not (Filename[I] in ShortForbiddenChars); end; end; 
+3
source share

Checking for a directory:

In SysUtils you have: DirectoryExists

Check file name:

Incorrect filenames are: \ / : * ? " < > | \ / : * ? " < > | so you can check the file name as follows:

 for c in AFileName do begin OK := NOT (C in ['\', '/', ':', '*', '?', '"', '<', '>', '|']); if not OK then Break; end; 

Checking the ability to write to the folder:

Duplicate: How can I use Delphi to check if I can write to a directory?

+2
source share

You can also use the SysUtils.CharInSet function:

 function isFileNameValid(fileNameToCheck : String) : Boolean; var invalidChars : Boolean; ch : Char; begin invalidChars := False; for ch in fileNameToCheck do begin invalidChars := SysUtils.CharInSet(ch, ['\', '/', ':', '*', '?', '"', '<', '>', '|']); if invalidChars then Break; end; Result := not invalidChars; end; 
+1
source share

Here is my solution:

 function ValidFileName(const FileName: String): Boolean; const InvalidChar: array[0..8] of Char = ('\', '/', ':', '*', '?', '"', '<', '>', '|'); var I, J, L: Integer; begin Result:= False; L:= Length(FileName); if (FileName = '') or (FileName[L] = '.') or (FileName[L] = ' ') then Exit; for I:= 1 to L do begin if (FileName[I] < ' ') then Exit; for J:= 0 to 8 do if FileName[I] = InvalidChar[J] then Exit; end; Result:= True; end; 
0
source share

This is my version:

 function MExtractFileName(const Name: String): String; var I: Integer; begin I:= Length(Name); while (I > 0) and (Name[I] <> '.') do Dec(I); if I = 0 then Result:= Name else Result:= Copy(Name, 1, I-1); end; function MValidFileName(AFileName: String): Boolean; const InvalidChar: array[0..8] of Char = ('\', '/', ':', '*', '?', '"', '<', '>', '|'); InvalidWords: array[0..21] of String = ('CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'); var I, J, L: Integer; begin Result:= False; L:= Length(AFileName); if (L = 0) or (L > 255) or (AFileName[L] = '.') or (AFileName[L] = ' ') then Exit; for I:= 1 to L do begin if (AFileName[I] < ' ') then Exit; for J:= 0 to 8 do if AFileName[I] = InvalidChar[J] then Exit; end; AFileName:= UpperCase(TrimRight(MExtractFileName(AFileName))); for I:= 0 to 21 do if AFileName = InvalidWords[I] then Exit; Result:= True; end; 
0
source share

All Articles