Delphi-PRAXiS

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)

juergen 27. Mai 2018 21:25

TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Hallo zusammen,


...
edt1.Text:= 'c:\Lieder\$$$$$$_sdsfdsfdsfdsfdsfsd321fdsfdsf31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f ds31fds321f1dsf1dsf31ds32f1ds1f3ds1f3d2sf1ds32f1ds 3fds3f1ds3f1ds31fds1f312dsf312dsf31ds1fds31fds32f1 dsf1ds3f1ds3f12ds13fds132fsed\27 - Ieva Zasimauskaitė (Lithuania) - When We're Old.mp3' // das sind 285 Zeichen...


Delphi-Quellcode:
var
  FS: TFileStream;
begin
  try
    FS := TFileStream.Create(edt1.Text, fmOpenRead);
  finally
    FS.Free;
  end;
end;

Laut Delphi Hilfe kann ich keine Grenze bei TFileStream wegen Pfadlänge oder Unicodezeichen erkennen.

Weiß jemand warum Delphi crasht und die Meldung bringt: Datei nicht gefunden?


Vielen Dank schon mal im Voraus!

mensch72 27. Mai 2018 21:55

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
NTFS Wikipedia:

...Dateinamen können... bis zu 255 Zeichen lang sein und aus fast beliebigen Unicode-Zeichen bestehen...
...eine maximale Länge des kompletten Pfadnamens von 32.767 Zeichen (allerdings beschränkt Windows bis zur Version Windows 10 Build 14352 die nutzbare Länge auf 260 Zeichen)...

EWeiss 27. Mai 2018 21:56

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Kann mir nur vorstellen das der Pfad einfach zu lang ist.
Mit dem FileStream hat das nichts zu tun.

MAX_PATH ?? 260.. du hast aber 285
oops da war jemand schneller.

gruss

juergen 27. Mai 2018 22:01

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Windows lässt die Pfadlänge > 260 zu und andere Programme kommen auch mit der Pfadlänge > 259 klar.
Ich hatte nun angenommen, dass TFileStream mit der Pfadlänge > 259 kein Problem hätte.
Im Moment weiß ich noch nicht wie ich das umgehen kann.

KodeZwerg 27. Mai 2018 22:07

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Wenn Du ein commandprompt öffnest und da diese Zeichenkette reinkopierst und Return drückst, was passiert?

edit
Zitat:

Hello,

Good news ! you can reach 260 !

BUT:

not with folders.

Because of the following rule: You should always be able to create a file with 12 chars in the name (including the extension, something like 8.3)

So, we have this:

c:\very-long-folder-name => MAX Length=(260-12-1) = 247. The trailing minus 1 is for the invisible NUL terminator.

Then, you can create a file in this folder with a name like this: 12345678.txt

So, we have our 260 chars for the whole path, including the file name, the extension, and the NUL terminator.

More details: https://msdn.microsoft.com/en-us/lib...47(VS.85).aspx
Also Verzeichnisname = 247 Zeichen sind max.
Helfen kann es den Namen in den ShortName umzuwandeln!

EWeiss 27. Mai 2018 22:18

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Ich denke es sind die Leerzeichen zwischen dem String.
Zitat:

sdsfdsfdsfdsfdsfsd321fdsfdsf31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f
Zudem sind in dem String ungültige Zeichen enthalten die Windows so nicht akzeptiert.
Kann jetzt aber nicht sagen ob der String den du hier reinkopiert hast verändert wird.

Windows meldet mir das die Datei nicht gefunden wird.

Zitat:

Helfen kann es den Namen in den ShortName umzuwandeln!
Wäre eine Möglichkeit ja..

gruss

KodeZwerg 27. Mai 2018 22:22

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Ich hab da eher das "$" Zeichen in Verdacht aber der TE soll mal was dazu sagen:wink:

EWeiss 27. Mai 2018 22:30

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

Zitat von KodeZwerg (Beitrag 1403115)
Ich hab da eher das "$" Zeichen in Verdacht aber der TE soll mal was dazu sagen:wink:

Nun ja ich kann die Datei gar nicht erst erstellen frage mich wie er das macht.
Gebe ich den String so unter Ausführen im Startmenü ein wird alles abgeschnitten was länger ist wie 260


gruss

juergen 27. Mai 2018 22:35

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Problem gelöst!
Es ist die Verwendung des MAX_Path die angewendet wird, wenn eine direkte Pfadangabe verwendet wird!
Wenn ich ein '\\?\' vor dem Pfad stelle, erkennt Windows dass es ein UNC Path ist (Windows Plattform abhängig). UNC hat *nicht* die Einschränkung von MAX_Path und es wird auf die entsprechende Windows-API umgeleitet.
Gut zu wissen...

...
edt1.Text:= '\\?\' + 'c:\Lieder\$$$$$$_sdsfdsfdsfdsfdsfsd321fdsfdsf31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f ds31fds321f1dsf1dsf31ds32f1ds1f3ds1f3d2sf1ds32f1ds 3fds3f1ds3f1ds31fds1f312dsf312dsf31ds1fds31fds32f1 dsf1ds3f1ds3f12ds13fds132fsed\27 - Ieva Zasimauskaitė (Lithuania) - When We're Old.mp3' // das sind 285 Zeichen...


So funktioniert nun alles.

Danke für die entsprechenden Hinweise auf MAX_PATH, weil ich nur nach TFileStream gesucht hatte! :dp:

EWeiss 27. Mai 2018 22:37

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Naja super wenn es jetzt geht.
Aber die frage bleibt wie erstellst du den Pfad unter Windows ?
Bei mir geht es nicht.

gruss

KodeZwerg 27. Mai 2018 22:43

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Explorer meckert bei mir nicht beim erstellen aber ich würde dennoch über ShortName gehen.
Grund: Ich habe schlechte Erfahrung gemacht wenn man was Schreiben will, nur zum Lesen ists ok.

EWeiss 27. Mai 2018 22:49

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

Zitat von KodeZwerg (Beitrag 1403121)
Explorer meckert bei mir nicht beim erstellen aber ich würde dennoch über ShortName gehen.
Grund: Ich habe schlechte Erfahrung gemacht wenn man was Schreiben will, nur zum Lesen ists ok.

Keine Ahnung was für ein System ihr habt.
Gebe ich den Namen hier kopiert bei mir so ein gibt's die Fehlermeldung wie im vorherigen Beitrag gezeigten Screeshot.

Und bei Auführen wird alles abgeschnitten und dieser Fehler siehe shot.
Hmmm.. hab wohl ein spezielles Window.

Na egal wenn es läuft ;) Hat mich nur mal interessiert.
Zitat:

wenn man was Schreiben will
Man muss es nur mal schreiben können.. bei mir geht's nicht.

gruss

juergen 27. Mai 2018 22:50

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

Zitat von EWeiss (Beitrag 1403119)
...
Aber die frage bleibt wie erstellst du den Pfad unter Windows ?
Bei mir geht es nicht.

gruss


Ausgangssituation war, das ein User mit meinem Programm seine Lieder nicht in mein Programm einlesen konnte. Es stellte sich dann heraus, dass seine Pfade länger 259 Zeichen waren. Die Ordner mit > 259 Zeichen hatte ich bei mir mit dem Total Commander erstellt. Aber auch mein Explorer erstellt Ordner > 260 Zeichen. (ich verwende das aktuelle Windows 10)

Zitat:

Zitat von mensch72 (Beitrag 1403108)
NTFS Wikipedia:

...Dateinamen können... bis zu 255 Zeichen lang sein und aus fast beliebigen Unicode-Zeichen bestehen...
...eine maximale Länge des kompletten Pfadnamens von 32.767 Zeichen (allerdings beschränkt Windows bis zur Version Windows 10 Build 14352 die nutzbare Länge auf 260 Zeichen)...


Könnte also an der Windowsversion liegen (du nutzt ja Windows 7) :wink:

KodeZwerg 27. Mai 2018 22:52

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

Zitat von EWeiss (Beitrag 1403117)
Nun ja ich kann die Datei gar nicht erst erstellen frage mich wie er das macht.

Ich bringe Dir mal ein wenig Windows bei :-)

Du willst c:\Lieder\$$$$$$_sdsfdsfdsfdsfdsfsd321fdsfdsf31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f ds31fds321f1dsf1dsf31ds32f1ds1f3ds1f3d2sf1ds32f1ds 3fds3f1ds3f1ds31fds1f312dsf312dsf31ds1fds31fds32f1 dsf1ds3f1ds3f12ds13fds132fsed erstellen und das kannst Du nicht.

Lösung, kopiere diese Zeichenkette, öffne commandprompt und tippe
md "c:\Lieder\$$$$$$_sdsfdsfdsfdsfdsfsd321fdsfdsf 31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f ds31fds321f1dsf1dsf31ds32f1ds1f3ds1f3d2sf1ds32f1ds 3fds3f1ds3f1ds31fds1f312dsf312dsf31ds1fds31fds32f1 dsf1ds3f1ds3f12ds13fds132fsed"
ein und drücke Return, was passiert? Hurra wir haben ein tolles Verzeichnis erstellt ^_^

EWeiss 27. Mai 2018 22:52

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

Könnte also an der Windowsversion liegen (du nutzt ja Windows 7)
jup.. Möglich Danke ;)
Zitat:

Ich bringe Dir mal ein wenig Windows bei
Muss du bestimmt nicht..
Was MakeDir ist, ist mir bekannt.

gruss

KodeZwerg 27. Mai 2018 22:55

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Da wir beide Windows 7 haben und es so bei mir funktioniert, wieso nicht auch bei Dir?

EWeiss 27. Mai 2018 23:03

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

Zitat von KodeZwerg (Beitrag 1403128)
Da wir beide Windows 7 haben und es so bei mir funktioniert, wieso nicht auch bei Dir?

Ganz einfach weil ich diesen String verwende.
md "c:\Lieder\$$$$$$_sdsfdsfdsfdsfdsfsd321fdsfdsf 31ds f1dsf1ds3f1dsf1ds3f1ds31fds31f1dsf1dsf31dsf321ds1f ds31fds321f1dsf1dsf31ds32f1ds1f3ds1f3d2sf1ds32f1ds 3fds3f1ds3f1ds31fds1f312dsf312dsf31ds1fds31fds32f1 dsf1ds3f1ds3f12ds13fds132fsed\27 - Ieva Zasimauskaite (Lithuania) - When We're Old.mp3"

So!
Und was sagt Window? Hurra der Pfad ist zu lang.
Und was ich nicht schreiben kann, kann ich auch nicht lesen. (zumindest nicht auf Win7)
OK ist egal..

gruss

KodeZwerg 27. Mai 2018 23:10

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
Ja ok, ich habs ohne Dateinamen, nur Verzeichnis.
Bin Deiner Meinung, Egal :thumb:

EWeiss 27. Mai 2018 23:14

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

Zitat von KodeZwerg (Beitrag 1403131)
Ja ok, ich habs ohne Dateinamen, nur Verzeichnis.
Bin Deiner Meinung, Egal :thumb:

Nur die Directory da passt es ja..
Und normalerweise gibt man den Dateinamen auch nicht mit an.
Denn man will ja einen Folder erstellen.

Wollte es aber destotrotz trotzdem mal versuchen ;) LOL

gruss

himitsu 28. Mai 2018 11:37

AW: TFileStream crasht bei Dateiname=285 Zeichen mit Unicode
 
"Leerzeichen" ... siehe "Zitat" des Posts ... das war das Forum (für erzwungenen Zeilenumbruch)

MAX_PATH = 260, inkl. Drive (C:\) und abschließender #0 = 256 für den "kompletten" Pfad


Mehr als 260 nur via UNC.

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:41 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