Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi binären Inhalt z.b PDF in einen String laden (https://www.delphipraxis.net/213499-binaeren-inhalt-z-b-pdf-einen-string-laden.html)

stalkingwolf 8. Aug 2023 11:15


binären Inhalt z.b PDF in einen String laden
 
Ich stelle mich glaube ich gerade etwas unfähig an.
Ich versuche eine Binäre Datei (z.b PDF,JPG) in einen String zu laden und bekomme nur Teile davon eingelesen.
Ich denke mein Lösungsansatz ist verkehrt.

Was ich machen muss.
Ein Drittanbieter mit welchem wir zusammenarbeiten will per REST-API den Dateiinhalt binär übertragen bekommen.
Allerdings mit einem Boundary drumherum im Body

also z.b
Code:
--__BOUNDARY__--
%PDF-1.3
1 0 obj
<</Type/Catalog/PageLayout/SinglePage/Pages 3 0 R>
.
.
.
--__BOUNDARY__--
Ich habe mehrere Wege probiert z.b
Code:
function LoadFileToString(const FileName: string): ansistring;
    var FileStream: TFileStream;
    begin
        FileStream := TFileStream.Create(FileName, fmOpenRead);
        try
            SetLength(Result, FileStream.Size);
            FileStream.Read(Pointer(Result)^, FileStream.Size);
        finally
            FileStream.Free;
        end;
    end;

    function BinaryoString(const filePath: string): string;
    var fs: TFileStream;
        ms: TMemoryStream;
    begin
        fs := TFileStream.Create(filePath, fmOpenRead);
        try
            ms := TMemoryStream.Create;
            try
                ms.CopyFrom(fs, fs.Size);
                SetString(Result, PAnsiChar(ms.Memory), ms.Size);
            finally
                ms.Free;
            end;
        finally
            fs.Free;
        end;
    end;

BerndS 8. Aug 2023 11:25

AW: binären Inhalt z.b PDF in einen String laden
 
Ich lese den Ansistring in etwa so ein:
Die 1. Funktion habe ich mal etwas angepasst.
Möglicherweise gibt es da auch schon was Fertiges.
Delphi-Quellcode:
function LoadFileToString(const FileName: string): AnsiString;
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Result, FileStream.Size);
    if FileStream.Size > 0 then
       FileStream.Read(Result[1], FileStream.Size);
   finally
     FileStream.Free;
   end;
end;

stalkingwolf 8. Aug 2023 11:44

AW: binären Inhalt z.b PDF in einen String laden
 
Das ist wie meine oben.

Mein Problem ist das ich das in eine Tstringlist packe damit ich meine Boundary drumherum bekomme und hier wohl was über die Wupper geht, weil danach das Resultat nicht mehr vollständig ist.

Ich habe einmal ChatGTP gefragt und der hat mir TIdMultiPartFormDataStream vorgeschlagen.
Aber dann meckert der Server das angeblich die Form nicht korrekt geschlossen wäre.

Edit : glaube ich habe auf StackOverflow was gefunden was mein Problem löst.
https://stackoverflow.com/questions/...ultipart-mixed

KodeZwerg 8. Aug 2023 12:10

AW: binären Inhalt z.b PDF in einen String laden
 
So vielleicht?
Delphi-Quellcode:
program project1;

uses
  SysUtils, Classes;

procedure ReadBinaryFile(const FileName: string; var Data: AnsiString);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Data, Stream.Size);
    Stream.ReadBuffer(Data[1], Stream.Size);
  finally
    Stream.Free;
  end;
end;

procedure WriteBinaryFile(const FileName: string; const Data: AnsiString);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    Stream.WriteBuffer(Data[1], Length(Data));
  finally
    Stream.Free;
  end;
end;

var
  head, foot, data: AnsiString;
begin
  head := '--__BOUNDARY__--' + LineEnding + '%PDF-1.3' + LineEnding + '1 0 obj' + LineEnding + '<</Type/Catalog/PageLayout/SinglePage/Pages 3 0 R>' + LineEnding;
  foot := LineEnding + '--__BOUNDARY__--';
  ReadBinaryFile('.\file.bin', data);
  WriteBinaryFile('.\file.bin' + '.new', head + data + foot);
  ReadLn;
end.

himitsu 8. Aug 2023 12:59

AW: binären Inhalt z.b PDF in einen String laden
 
Grundsätzlich: Eine binäre Datei wird auch binär gelesen, damit man nicht bei der StringBearbeitung kaputt macht.
* gut, Delphi-Strings haben kein Problem mit einer #0 im String
* aber z.B. bei einer TStringList der TFile.ReadAllLines die Zeilenumbrüche
* und vor allem Konvertieurungen, bei der Behandlung der Datei mit einer "falschen" CodePage.


Deine Codes lesen definitiv immer alles, ABER

* wegen dem "String" beim zweiten Code, ist natürlich der halbe String am Ende "leer".
string = hat seit Delphi 2009 zwei Bytes pro Char

* und weil du keine Fehlerprüfung hast, könnte auch weniger gelesen werden (hier an deinen Beispielen aber nicht, außer z.B. Dateisystem oder Datenträger sind kaputt)
-> Read und dessen Result prüfen, oder eben ReadBuffer




TStream / TMemoryStream, TFileStream, TStringStream
RawByteString
TBytes

Delphi-Referenz durchsuchenTFile.ReadAllBytes
Delphi-Referenz durchsuchenTFile.ReadAllText aber hier möglichst mit einer ANSI- ASCII-CodePage arbeiten, weil wegen String/UnicodeString
es gab auch mal irgendwo eine CodePage ohne Umrechnung, wo #0-#255 1:1 umgesetzt werden, ohne Konvertierung
https://learn.microsoft.com/en-us/wi...ge-identifiers

stalkingwolf 8. Aug 2023 14:03

AW: binären Inhalt z.b PDF in einen String laden
 
mit TFile hatte ich auch schon getestet.

Mein Problem war das in der Test PDF welche ich genutzt habe in einem der Stream Parts ein Nullzeichen enthalten war und somit immer exakt dort Ende war.

Hatte mir das ganze nun in einen Stream, dann diesen auf die Platte geschrieben. Sah alles gut aus.
Als ich per Copy&Paste das ganze in den RESTClient kopieren wollte hatte ich wieder den gleichen Teil eingefügt.

himitsu 8. Aug 2023 14:57

AW: binären Inhalt z.b PDF in einen String laden
 
Zitat:

Zitat von stalkingwolf (Beitrag 1525420)
Mein Problem war das in der Test PDF welche ich genutzt habe in einem der Stream Parts ein Nullzeichen enthalten war und somit immer exakt dort Ende war.

Definitiv NEIN, also auf den String bezogen.

Wie/wo schaust du dir denn den Inhalt des Strings an?
* Debugger sagt alles OK
* in ein TMemo kopiert oder an ShowMessage übergeben ... ja, selbst Schuld, da PChar und nicht Delphi-String

Und nun rate mal, warum man Binärdaten möglichst nicht in Strings packt. (ja, es geht, wenn man aufpasst, aber)

Neutral General 9. Aug 2023 10:37

AW: binären Inhalt z.b PDF in einen String laden
 
Ich verstehe nicht warum die PDF in einen String geladen werden muss :gruebel:

1) Schreib "--__BOUNDARY__--" in einen (Memory)Stream
2) Lade die PDF in einen 2. Stream und kopier den Inhalt danach in den 1. Stream mit CopyFrom
3) Schreib "--__BOUNDARY__--" in den Stream
4) Stream versenden
5) Fertig

Sherlock 9. Aug 2023 11:23

AW: binären Inhalt z.b PDF in einen String laden
 
Oder encodiere den binären Stream zu Base64 (https://docwiki.embarcadero.com/Libr...Base64Encoding) packe ihn problemlos in Deinen String und decodiere ihn wieder zurück, wenn Du am Ziel bist.

Sherlock

stalkingwolf 9. Aug 2023 16:15

AW: binären Inhalt z.b PDF in einen String laden
 
Zitat:

Zitat von Neutral General (Beitrag 1525432)
Ich verstehe nicht warum die PDF in einen String geladen werden muss :gruebel:

1) Schreib "--__BOUNDARY__--" in einen (Memory)Stream
2) Lade die PDF in einen 2. Stream und kopier den Inhalt danach in den 1. Stream mit CopyFrom
3) Schreib "--__BOUNDARY__--" in den Stream
4) Stream versenden
5) Fertig

weil ich ganz den Body in einer Tstringlist zusammenbauen wollte bzw. wir das so machen und dann an IDHTTP übergeben.
Aber normalerweise machen wir das immer Base64 codiert nur dieser Anbieter will es halt binär.

Ich habe das ganze Thema nun auch über einen Stream gelöst und genau so wie du oben beschrieben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:39 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz