Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TFileStream crasht bei Dateiname=285 Zeichen mit Unicode (https://www.delphipraxis.net/196510-tfilestream-crasht-bei-dateiname%3D285-zeichen-mit-unicode.html)

KodeZwerg 28. Mai 2018 11:46

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
@himitsu: ShortName ....
Delphi-Quellcode:
function GetShortPathString(sLongPathName : string) : string;
begin
  Result:='';
  SetLength(Result,MAX_PATH+1);
  GetShortPathName(PChar(sLongPathName),PChar(Result),MAX_PATH);
  SetLength(Result,StrLen(PChar(Result)));
end;

himitsu 28. Mai 2018 11:51

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Aber auch nur wenn das aktiv ist.

Standardmäßig generiert Windows/NTFS seit paar Jahren keine Kurznamen mehr (solange kein Programm explizit ANSI-File-APIs nutzt und da der lange Name nicht rein passt), wenn ich mich Recht erinner.



Delphi-Quellcode:
function GetShortPathString(const sLongPathName : string) : string;
begin
  SetLength(Result, MAX_PATH-1); // LongString im Delphi haben zwar eine Längenangabe, aber für einfache Casts auch implizit zwei #0 am Ende (der ShortString ein Längenbyte ohne #0)
  SetLength(Result, GetShortPathName(PChar(sLongPathName), PChar(Result), MAX_PATH)); // und man mag es nicht glauben, aber es soll WinAPIs geben, die haben ein Result, dass man nutzen kann
end;

KodeZwerg 28. Mai 2018 12:05

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Nette Umleitung:thumb:
Zitat:

If you call GetShortPathName on a path that doesn't have any short names on-disk, the call will succeed, but will return the long-name path instead. This outcome is also possible with NTFS volumes because there's no guarantee that a short name will exist for a given long name.
Von daher, Du hast Recht!

Alex_ITA01 22. Sep 2022 09:29

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Hallo zusammen,
ich habe ein ähnliches Problem und die Angabe des UNC Namen hilft bei mir leider nicht.

Diese Variante geht nicht (Fehlermeldung bei TFileStream.Create(OutputFileName))
Delphi-Quellcode:
var
  InputStream, OutputStream: TFileStream;
  InputFileName, OutputFileName: String;
begin
  InputFileName := 'C:\Temp\Test.txt';
  OutputFileName := '\\x.x.x.x\l\MeinOrdner\_Transfer\H_I_E_R_L_I_E_G_T_E_I_N_O_R_D_N_E_R\J_A_H_R\M_O_N_A_T\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N';

  InputStream := TFileStream.Create(InputFileName, fmOpenRead);
  try
    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
    try

    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
Diese Variante geht (KEINE Fehlermeldung)
Delphi-Quellcode:
var
  InputStream, OutputStream: TFileStream;
  InputFileName, OutputFileName: String;
begin
  InputFileName := 'C:\Temp\Test.txt';
  OutputFileName := '\\x.x.x.x\l\MeinOrdner\_Transfer\H_I_E_R_L_I_E_G_T_E_I_N_O_R_D_N_E_R\J_A_H_R\M_O_N_A_T\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S';

  InputStream := TFileStream.Create(InputFileName, fmOpenRead);
  try
    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
    try

    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
Wie bekomme ich es hin, dass die Max_Path Angabe nicht genommen wird?
Habe Windows 10 64x

himitsu 22. Sep 2022 09:41

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Zitat:

Wie bekomme ich es hin, dass die Max_Path Angabe nicht genommen wird?
Das machen, was in der Hilfe steht?

Die LongPaths im Windows und Programm aktivieren und dann kann CreateFile/TFileStream/... eientlich auch mehr.

https://learn.microsoft.com/de-de/wi...?tabs=registry
https://learn.microsoft.com/en-us/wi...?tabs=registry


Und beim Lesen von Pfaden nicht vergessen aufzupassen, dass ihr im Programm keine statischen Puffer mit MAX_PATH benutzt.
Genau deswegen muß man es explizit aktivieren, weil Viele bei statschen Puffern gern vergessen die Rückgaben zu prüfen, weil kann konnte ja (früher) eh nicht mehr sein.



Außerdem \\?\... oder \\?\UNC\server\share\... und nicht \\server\share\... :gruebel:

Alex_ITA01 22. Sep 2022 09:46

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Das muss doch auch anders gehen.
Im TotalCommander kann ich mit F7 auch direkt mehrere Ordner erzeugen in dem Eingabefeld, wenn ich eine Ordnertiefe > 260 Zeichen eingebe und da habe ich nichts im Windows umgestellt.
In meiner Anwendung kann ich ja gerne irgendwas machen, damit es geht aber im Windows möchte ich nichts verstellen, weil die Anwendung auf x-Rechnern läuft und wie gesagt, der TotalCommander kann es doch auch ohne Windows Änderung.

Alex_ITA01 22. Sep 2022 10:18

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Hab es testhalber mal gemacht und die Funktion im Windows aktiviert:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\FileSystem\LongPathsEnabled

Rechner neugestartet


Geht immernoch nicht:
Delphi-Quellcode:
  OutputFileName := '\\x.x.x.x\l\MeinOrdner\_Transfer\H_I_E_R_L_I_E_G_T_E_I_N_O_R_D_N_E_R\J_A_H_R\M_O_N_A_T\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N';
Geht auch nicht:
Delphi-Quellcode:
  OutputFileName := '\\?\x.x.x.x\l\MeinOrdner\_Transfer\H_I_E_R_L_I_E_G_T_E_I_N_O_R_D_N_E_R\J_A_H_R\M_O_N_A_T\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N\';
  OutputFileName := OutputFileName + 'D_A_S_I_S_T_E_I_N_T_E_S_T_M_I_T_E_I_N_E_M_L_A_N_G_E_N_N_A_M_E_N';
Welchen Trick gibt es noch?

BerndS 22. Sep 2022 10:37

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Du solltest auch die letze Zeile von Hitsumi beachten.
Siehe http://msdn.microsoft.com/en-us/libr...9.aspx#maxpath

Wir haben eine Funktion, die das automatische macht.
Delphi-Quellcode:
function LongFileName(AFileName: string): string;
var
  MaxPath: Word;
begin
  Result := AFileName;
  MaxPath := Length(ExtractFilePath(AFileName));
  // der Pfad darf nur 247 Zeichen lang sein
  // 12 Zeichen sind für den Dateinamen reserviert
  if (MaxPath >= MAX_PATH - 12) and (Copy(AFileName, 1, 4) <> '\\?\') then
    if Copy(AFileName, 1, 2) = '\\' then
      Insert('\?\UNC', Result, 2)
    else
      Result := '\\?\' + Result;
end;

Alex_ITA01 22. Sep 2022 10:48

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Ok, da hatte ich die \\? Formatierung falsch verstanden.
Habe deine Funktion genommen aber ohne das "ExtractFilePath", der Pfad ist ja nicht das Problem, der Dateiname macht dann die Länge > 260 Zeichen. Geht jetzt. Danke


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 Uhr.
Seite 3 von 3     123   

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