AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Datei-Transfer mit DragAndDropComponentSuite
Thema durchsuchen
Ansicht
Themen-Optionen

Datei-Transfer mit DragAndDropComponentSuite

Ein Thema von harfes · begonnen am 13. Jul 2024 · letzter Beitrag vom 16. Jul 2024
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#11

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 14. Jul 2024, 13:24
Erstmal nein, bei diesen API liegt (derzeit) nicht der Fehler.
Womit man aber aufpassen muss, dass wenn die Datei nicht existiert, diese Funktionen nichts (0) zurückgeben. (z.B. wenn hier Buchstaben am Ende fehlen)
Das, was ich bisher testen konnte, da war bereits vor dem GetLongPathName der String abgeschnitten.

LongStrings, wie AnsiString und UnicodeString/String, enthalten immer zwei folgende #0#0, damit PChar sich ohne Probleme direkt ableiten lässt.
So lange dort hinten eine #0 reingeschrieben wird, ist es egal.

Viele nutzten GetMem und Co. für den Zwischenspeicher des Strings, inkl. der letzten #0.
Andere nutzen einen String, aber reservieren im String auch einen Platz für die letzte #0, welche sie abschließend nochmals abschneiden.
Ich finde es unschön, hier unnötig den kompletten Stringspeicher unnötig umher kopieren zu müssen.
Delphi-Quellcode:
class function TForm25.GetShortName(Filename: string): string;
begin
  SetLength(Result, GetShortPathName(PChar(Filename), nil, 0));
  SetLength(Result, Integer(GetShortPathName(PChar(Filename), PChar(Result), Length(Result))) - 1);
end;
Und außerdem sind diese beiden API echt pervers.
Sind sie erfolgreich, dann ist im Result keine abschließende #0 enthalten, aber im Falle eines Fehlers, ist die #0 doch mit drin.
OK -> Result sind nur die kopierten Zeichen (ohne #0)
ERROR, aka Speicher zu klein -> Result ist der komplett nötige Speicher, in Zeichen, inkl. der #0




.msg versteht im Grunde nur Outlook.
.eml verstehen nahezu alle Mailprogramme.
Und im integrierten Indy ist die Behandlung der EML enthalten.
Wir nutzen es zum Senden von Mails, über das Standardmailprogramm, inkl. Anhänge und Formatierungen, was in der MAPI offiziell nicht vorgesehen ist.
$2B or not $2B

Geändert von himitsu (14. Jul 2024 um 14:12 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
353 Beiträge
 
#12

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 14. Jul 2024, 15:05
Sorry, i still don't understand the need to manually strip the terminating #0, you could simply use this
Code:
class function TForm25.GetShortName(Filename: string): string;
var
  Len: Integer;
begin
  Len := GetShortPathName(PChar(Filename), nil, 0);
  SetLength(Result, Len);
  Len := GetShortPathName(PChar(Filename), PChar(Result), Len);
  SetLength(Result, Len);
  Result := Trim(Result); // will remove terminating #0s if there is any
end;
I am also not a fan of juggling strings, but with two line of Pascal the compiler is producing very close instructions as longer and more readable suggested above, so no real performance degradation, on other hand the lack of "const Filename: string" have more impact performance wise.
One more thing, once the data (aka string in this case) is in the Delphi/Pascal string realm there is no reason to keep the terminating #0, on the contrary it is more concise to strip them with Trim().
After that if you want to check or validate the result then use FileExist or any equivalent.

Also i want to point to the fact with -1 in the code in previous post, there was an overflow with one char, this is hidden with FastMM and even EurekaLog might fail to detect such small overflow because it is smaller than 32bit, (rare cases but there are there specially with strings do the in consistency in RTL, strings and reserve #0), but i can imagine cases with specific length where the length is a multiplication of specific n (n= 4, 8, 16..) and your code did call some allocation after getting the paths, next allocation was also a string and it was empty, causing to fill the last char with 0 in your path/file name, this can explain the successful result most the time but not every time and also explain the difficulty in reproducing, so try to replicate your test with exact path and file length, don't use arbitrary, or go with full brut force from the shortest to longest and see if or when it will fail reliably.
Kas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#13

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 16. Jul 2024, 13:32
Du weißt, dass DropFileTarget1.Files.SaveToStream aka StringList.SaveToStream
die Liste der Dateinamen ist, und nicht der Inhalt dieser Datei?

SaveToFile/SaveToStream sollte beim TMemoryStream (eigentlich) immer den kompletten Inhalt speichern,
aber grundsätzlich kann es nicht schaden, es auf den Anfang zu setzen.
z.B. TBitmap.LoadFromStream/SaveToStream arbeitet von der aktuellen Position aus
und nach DropFileTarget1.Files.SaveToStream steht der Zeiger hinter den eingefügten Daten.
Delphi-Quellcode:
mem.Position := 0;
mem.SaveToFile(FilepathB);
Warum ein TMemoryStream mit anschließendem SaveToFile, anstatt direkt ein TFileStream?

PS: Delphi-Referenz durchsuchenTFile.Create aus System.IOUtils
Mit "Create" auf die Datei bezogen, nicht auf den Stream, also auch .Open, .OpenRead, .OpenWrite oder .Append
Delphi-Quellcode:
Stream := TFile.Create(TPath.Combine(Zielpfad, FileName)); // oder eben := TFileStream.Create(...);
try
  DropFileTarget1.Files.SaveToStream(Stream);
finally
  Stream.Free;
end;




Delphi-Quellcode:
class function TForm25.GetShortName(Filename: string): string;
begin
  // Check size and contact storage manager(s)
  SetLength(Result, GetShortPathName(PChar(Filename), nil, 0) - 1);
  // only fill the variable content (no interaction with the memory manager)
  GetShortPathName(PChar(Filename), PChar(Result), Length(Result) + 1);
end;

class function TForm25.GetShortName(Filename: string): string;
begin
  // Check size and contact storage manager(s)
  SetLength(Result, GetShortPathName(PChar(Filename), nil, 0));
  // Fill variable content,
  // reserve new memory,
  // copy content
  // and release old memory
  SetLength(Result, Integer(GetShortPathName(PChar(Filename), PChar(Result), Length(Result))) - 1);
end;

class function TForm25.GetShortName(Filename: string): string;
var
  Len: Integer;
begin
  // Check size
  Len := GetShortPathName(PChar(Filename), nil, 0);
  // and contact storage manager(s)
  SetLength(Result, Len);
  // Fill variable content,
  Len := GetShortPathName(PChar(Filename), PChar(Result), Len);
  // change the size of the reserved memory (if inplace is not possible, then reserve new memory, copy content and release old memory)
  SetLength(Result, Len);
  // if truncated, then reserve new memory, copy content and release old memory
  Result := Trim(Result);
end;
$2B or not $2B

Geändert von himitsu (16. Jul 2024 um 13:34 Uhr)
  Mit Zitat antworten Zitat
harfes

Registriert seit: 25. Jun 2006
Ort: Rand der Scheibe
199 Beiträge
 
Delphi 12 Athens
 
#14

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 16. Jul 2024, 18:19
@himitsu: das mit mem.Position:=0 habe ich ausprobiert...leider keine Änderung (die Datei wird weiterhin erstellt an der richtigen Stelle - aber ohne Inhalt). Wie ich schon vermutet habe (und Du ja auch), sind in DropFileTarget1.Files.SaveToStream keine Daten enthalten, sondern nur der Dateiname.

Die Frage ist, wie komme ich an den Inhalt der Datei und wie kann ich den dann wieder (woanders) speichern? Meine Hoffnung war/ist, dass das hier schon mal jemand umgesetzt hat und einen Tipp geben kann. Die zu den Komponenten gehörigen Demos finde ich nicht gerade sehr aussagekräftig und sie funktionieren teilweise auch nicht wirklich...

Hartmut
Hartmut
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#15

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 16. Jul 2024, 19:25
keine Daten enthalten, sondern nur der Dateiname
Nja, aber dann müsste ja dennoch der Dateiname+Pfad in der Datei in der Datei drin stehen.

Hier DropFileTarget1.Files[0] war er es ja scheinbar noch.


Es gibt zwar ein "unnötiges" DropFileTarget1.Files.Clear, aber das erst ganz am Ende.
$2B or not $2B
  Mit Zitat antworten Zitat
harfes

Registriert seit: 25. Jun 2006
Ort: Rand der Scheibe
199 Beiträge
 
Delphi 12 Athens
 
#16

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 16. Jul 2024, 19:34
Naja, der Dateiname ist ja vorhanden, der Pafd kann ja nicht vorhanden sein beim Ziehen aus Outlook. Du kannst Dir ja gerne mal die Komponenten von GitHub ziehen und schauen:

https://github.com/landrix/The-Drag-...ite-for-Delphi

Vielleicht übersehe ich ja was ganz einfaches...das ist wieder der Wald mit den vielen Bäumen...

Hartmut
Hartmut
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#17

AW: Datei-Transfer mit DragAndDropComponentSuite

  Alt 16. Jul 2024, 19:51
Aber dennoch, über FileName:=ExtractFilename(DropFileTarget1.Files[0]); wird ja ein Dateiname dort rausgeholt.
Und demnach ist in DropFileTarget1.Files etwas drin, was dann via SaveToStream in der Datei landen müsste.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:29 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