Recent

Author Topic: Pathname conversion  (Read 3389 times)

Kaller

  • Jr. Member
  • **
  • Posts: 73
Pathname conversion
« on: August 30, 2023, 11:52:49 am »
How do I convert a directory path like c:\more\of\this\  to match the actual character case of windows file store?

Zvoni

  • Hero Member
  • *****
  • Posts: 3376
Re: Pathname conversion
« Reply #1 on: August 30, 2023, 12:30:36 pm »
How do I convert a directory path like c:\more\of\this\  to match the actual character case of windows file store?
Haven't understood a word.

Example?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: Pathname conversion
« Reply #2 on: August 30, 2023, 12:41:06 pm »
the user enters a path like c:\my\work\
the system says path found: C:\My\Work
because the folders are named My and Work

Zvoni

  • Hero Member
  • *****
  • Posts: 3376
Re: Pathname conversion
« Reply #3 on: August 30, 2023, 12:49:39 pm »
the user enters a path like c:\my\work\
the system says path found: C:\My\Work
because the folders are named My and Work
Your point?
The Windows Filesystem is Case-Insensitive ("c:\my\work\" = "C:\My\Work\")
so i don't know what you want to achieve.
What is the expected Result you want to get? "Path not found" or what?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

bonmario

  • Sr. Member
  • ****
  • Posts: 346
Re: Pathname conversion
« Reply #4 on: August 30, 2023, 12:52:39 pm »
How do I convert a directory path like c:\more\of\this\  to match the actual character case of windows file store?

Try this:
https://www.freepascal.org/docs-html/rtl/sysutils/expandfilenamecase.html

Hi, Mario

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: Pathname conversion
« Reply #5 on: August 30, 2023, 01:02:17 pm »
@BonMario: I tried without success. @Zvoni  What if files get migrated for example? I think knowing the actual case is a reasonable request.
« Last Edit: August 30, 2023, 01:17:50 pm by Kaller »

bonmario

  • Sr. Member
  • ****
  • Posts: 346
Re: Pathname conversion
« Reply #6 on: August 30, 2023, 01:26:19 pm »
I tried it now, and it works fine for me.
I use windows 11

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: Pathname conversion
« Reply #7 on: August 30, 2023, 01:35:11 pm »
I got it working. :) Have to specify fcmExact. 
« Last Edit: August 30, 2023, 02:01:25 pm by Kaller »

bonmario

  • Sr. Member
  • ****
  • Posts: 346
Re: Pathname conversion
« Reply #8 on: August 30, 2023, 01:42:02 pm »
Code: Pascal  [Select][+][-]
  1.   procedure LeggiNomeFileRealeDaDisco(var NomeSrcReale: String);
  2.   var NomeFileInp, NomeFileOut:String;
  3.       Posx:Integer;
  4.       MatchFound: TFilenameCaseMatch;
  5.   begin
  6.     //Inizializzazione variabili di lavoro
  7.     NomeFileInp:=NomeSrcReale;
  8.     NomeFileOut:='';
  9.  
  10.     while (NomeFileInp <> '') do begin
  11.       {$IFDEF MSWINDOWS}
  12.         if (Length(NomeFileInp) = 3) and
  13.            (NomeFileInp[2] = ':') then begin
  14.           NomeFileOut:=UpperCase(ExtractFileDrive(NomeFileInp)) + NomeFileOut;
  15.           NomeFileInp:='';
  16.         end;
  17.       {$ELSE}
  18.         if (NomeFileInp = PathDelim) then begin
  19.           NomeFileOut:=PathDelim + NomeFileOut;
  20.           NomeFileInp:='';
  21.         end;
  22.       {$ENDIF}
  23.  
  24.       if (NomeFileInp <> '') then begin
  25.         NomeFileOut:=ExtractFileName(ExpandFileNameCase(NomeFileInp, MatchFound)) + NomeFileOut;
  26.         Posx:=Pos(PathDelim, NomeFileInp);
  27.         if (Posx > 0) then begin
  28.           NomeFileOut:=PathDelim + NomeFileOut;
  29.         end else begin
  30.           NomeFileInp:='';
  31.         end;
  32.         NomeFileInp:=ExtractFileDir(NomeFileInp);
  33.       end;
  34.     end;
  35.  
  36.     //Valorizzazione finale dell'output
  37.     NomeSrcReale:=NomeFileOut;
  38.   end;
  39.  


If i use this code:
Code: Pascal  [Select][+][-]
  1. var NomeDir:String;
  2.     NomeDir:='c:\users\bonmar\downloads';
  3.     LeggiNomeFileRealeDaDisco(NomeDir);
  4.     ShowMessage(NomeDir);
  5.  

the output is this:
Code: Pascal  [Select][+][-]
  1. C:\Users\BONMAR\Downloads

Hi, Mario

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: Pathname conversion
« Reply #9 on: August 30, 2023, 02:03:03 pm »
Nice. Thanks.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Pathname conversion
« Reply #10 on: August 30, 2023, 02:06:11 pm »
My try, should be crosscompile compatible:
Code: Pascal  [Select][+][-]
  1. function SensitivePath(const APath: string): string;
  2.   function GetCurrent(const APath: string): string;
  3.   var
  4.     searchRec: TSearchRec;
  5.   begin
  6.     Result := '';
  7.     if FindFirst(ExcludeTrailingBackslash(APath), faAnyFile, searchRec) = 0 then
  8.     begin
  9.       Result := searchRec.Name;
  10.       FindClose(searchRec);
  11.     end;
  12.   end;
  13. var
  14.   s: string;
  15.   i: Integer;
  16.   arr: TStringArray;
  17. begin
  18.   if ((not FileExists(APath)) and (not DirectoryExists(APath))) then
  19.     Exit(APath);
  20.   s := '';
  21.   Result := '';
  22.   arr := APath.Split([PathDelim]);
  23.   for i := Low(arr) to High(arr) do
  24.     begin
  25.       s := s + arr[i] + PathDelim;
  26.       if i > 0 then
  27.         arr[i] := GetCurrent(s);
  28.       Result := Result + arr[i] + PathDelim;
  29.     end;
  30.   Result := ExcludeTrailingBackslash(Result);
  31. end;
Only tested with path, not filenames.

//edit:
Works for both same good, files, folder.

My test:
Code: Pascal  [Select][+][-]
  1.   WriteLn(SensitivePath('c:\windows\SysteM32'));
  2.   WriteLn(SensitivePath('c:\WindOws\SyStem32\'));
  3.   WriteLn(SensitivePath('c:\WinDows\SystEm32\D3D12CorE.Dll'));
The Result:
Quote
c:\Windows\System32
c:\Windows\System32\
c:\Windows\System32\D3D12Core.dll
« Last Edit: August 30, 2023, 08:40:43 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Bart

  • Hero Member
  • *****
  • Posts: 5721
    • Bart en Mariska's Webstek
Re: Pathname conversion
« Reply #11 on: August 30, 2023, 09:07:52 pm »
function FindDiskFileName in FileUtils might be what you are looking for.

Bart

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: Pathname conversion
« Reply #12 on: August 30, 2023, 10:38:24 pm »
On further investigation I think I understand the issues I was having. It appears that standard filename functions are not the answer, they do things like only work with the last item in the path. So even something like a trailing path delimiter will throw them off.   The routines provided by helpful posters here will be great.  Is it possible to get a directory without having to physically enter it?
I got GPT to convert Mario's code to English and compress it.
« Last Edit: August 30, 2023, 11:48:06 pm by Kaller »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Pathname conversion
« Reply #13 on: August 31, 2023, 12:13:58 am »
Is it possible to get a directory without having to physically enter it?
No.
If you want to have it like it is on disk than you must access disk, sound logical or?
Everything else is just to beautify a string but not to get it like you wanted to have.
I got GPT to convert Mario's code to English and compress it.
Uhm... applause?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Kays

  • Hero Member
  • *****
  • Posts: 632
  • Whasup!?
    • KaiBurghardt.de
Re: Pathname conversion
« Reply #14 on: August 31, 2023, 12:16:02 am »
[…] The Windows Filesystem
“The Windows Filesystem”? Jesus Christ.
Case-Insensitive […]
Meanwhile NTFS does support case-sensitive filenames. You will need to traverse the entire path checking each directory whether it has case-sensitive filename support enabled.
the user enters a path like c:\my\work\
the system says path found: C:\My\Work
I bet the WinAPI (or other essential library) provides some sort of canonicalize pathname function. Evidently you lack understanding of NTFS, so I strongly advise against implementing a mechanism by yourself.
Yours Sincerely
Kai Burghardt

 

TinyPortal © 2005-2018