AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Speichern in BlobField zerschießt MemorySTream

Ein Thema von dataspider · begonnen am 16. Mär 2023 · letzter Beitrag vom 17. Mär 2023
Antwort Antwort
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#1

Speichern in BlobField zerschießt MemorySTream

  Alt 16. Mär 2023, 11:06
Ich bin jetzt wirklich am Verzweifeln.
Ich konvertiere von WPRichText nach DevExpress RichEditControl.

Das mache ich mit einem MemoryStream.
In meinem Konverter schreibe ich zum Test den Stream in ein File. (stream.rtf)

Delphi-Quellcode:
procedure TConvertWPRichText.ParseStream(AStream: TMemoryStream);
Var
  I: Integer;
  LStream: TMemoryStream;
  LMergeField: TMergeField;
  LNewText: Ansistring;
  LNextPos: Integer;
begin
  if (MergeFields.Count = 0) then
    Exit;
  LStream := TMemoryStream.Create;
  try
    AStream.Position := 0;
    LStream.CopyFrom(AStream);
    LStream.Position := 0;
    AStream.Clear;
    AStream.CopyFrom(LStream, FMergeFields[0].Position); // bis zum ersten Feld
    for I := 0 to MergeFields.Count - 1 do
    begin
      LMergeField := FMergeFields[I];
      LNewText := LMergeField.GetNewText;
      AStream.WriteBuffer(LNewText[1], Length(LNewText)); // neues Feld
      LStream.Seek(Length(LMergeField.Text) + 1, soFromCurrent); // Ende erstes Feld
      if I = MergeFields.Count - 1 then
        AStream.CopyFrom(LStream, LStream.Size - LStream.Position)
      else
      begin
        LNextPos := MergeFields[I + 1].Position;
        AStream.CopyFrom(LStream, LNextPos - LStream.Position);
      end;
    end;
  finally
    LStream.Free;
  end;
end;
Den Inhalt des Stream schreibe ich dann in die Datenbank

Delphi-Quellcode:
procedure TFRMEdtTextDokument.LoadTextFromDB;
var
  LStream: TMemoryStream;
begin
  if IsDestroying then
    Exit;
  RichEditControl.Clear;
  if (DM.qryMain.FieldByName('DOKUMENT').IsNull) and (DM.qryMain.FieldByName('BRIEF').IsNull) then
    Exit;
  if (DM.qryMain.FieldByName('DOKUMENT').IsNull) then
  begin
    LStream := TMemoryStream.Create;
    try
      TBlobField(DM.qryMain.FieldByName('BRIEF')).SaveToStream(LStream);
      TConvertWPRichText.Convert(LStream);
      {$IFDEF DEBUG}
        LStream.SaveToFile('stream.rtf');
      {$ENDIF}
      LStream.Position := 0;
      DM.qryMain.Edit;
      TBlobField(DM.qryMain.FieldByName('DOKUMENT')).LoadFromStream(LStream);
      DM.qryMain.Post;
    finally
      LStream.Free;
    end;
  end;
  RichEditControl.LoadFromBlobField(TBlobField(DM.qryMain.FieldByName('DOKUMENT')));
end;
Auch hier schreibe ich den Stream in eine Datei.

In den Anlagen sind 2 rtf's
stream.rtf vor dem Speichern in DB
datenbankfeld.rtf - was in der Datenbank ankommt.

Wenn ich mit IBExpert die Datei stream.rft in das Feld lade, ist es OK.

Warum kommt in der DB der Müll an?

Frank
Angehängte Dateien
Dateityp: zip streamfiles.zip (26,1 KB, 5x aufgerufen)
Dateityp: pas rf.ConvertWPRichText.pas (7,4 KB, 3x aufgerufen)
Frank Reim
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#2

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 16. Mär 2023, 12:19
Bei der Konvertierung wird anscheinend ein Bild im Binary Format eingefügt:

{\pict\jpegblip\picw4416\pich1027\picwgoal4416\pic hgoal1027
\bin28150 ÿØÿà...

Speichern in der Datenbank mit einem Text-Encoding (ANSI, UTF-8 ...) kann dann zu Problemen führen. Speichern in ein Blob ohne Encoding/Textkonvertierung sollte funktionieren.

Alternative Idee: vielleicht kann DevExpress RichEditControl die Bilder anstatt Binär im Hex-Format ablegen. Das hat dann einen größeren Platzbedarf, besteht aber aus ASCII Daten.

Merke: die RTF Spezifikation sieht auch das Ablegen von reinen Binärdaten in der Datei vor.

Happy coding
Michael Justin
habarisoft.com

Geändert von mjustin (16. Mär 2023 um 12:33 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 16. Mär 2023, 13:21
Bei der Konvertierung wird anscheinend ein Bild im Binary Format eingefügt:

{\pict\jpegblip\picw4416\pich1027\picwgoal4416\pic hgoal1027
\bin28150 ÿØÿà...
Das ist richtig, darum ist es in der DB ein Binäres Blob (Firebird) und deshalb benutze ich TMemoryStream.
Ich dachte immer, TMemoryStream kümmert sich nicht um EnCoding.

Speichern in der Datenbank mit einem Text-Encoding (ANSI, UTF-8 ...) kann dann zu Problemen führen. Speichern in ein Blob ohne Encoding/Textkonvertierung sollte funktionieren.
Wie geht "Speichern in ein Blob ohne Encoding/Textkonvertierung"?
Ich habe auch in ParseStream versucht, anstatt mit AnsiString mit TBytes zu arbeiten bei Stream.WriteBuffer. Bringt auch keine Änderung.

Alternative Idee: vielleicht kann DevExpress RichEditControl die Bilder anstatt Binär im Hex-Format ablegen. Das hat dann einen größeren Platzbedarf, besteht aber aus ASCII Daten.
Also DevExpress legt die Bilder nicht binär ab. WPTools macht das. Aber ob ich das beeinflussen kann, weiß ich nicht.
Wäre auch nicht die Lösung, da ich ca. 1000 Einträge konvertieren muss.
Durch meine Routine sollte das automatisch passieren. Deshalb bei 2. Feld mit anderem Namen.

Ich bin mir ziemlich sicher, dass es nur die Zeile mit WriteBuffer ist. Aber ich komme nicht weiter.

Dennoch - Vielen Dank!

Frank
Frank Reim

Geändert von dataspider (16. Mär 2023 um 13:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 16. Mär 2023, 17:30
Ich dachte immer, TMemoryStream kümmert sich nicht um EnCoding.
Das ist Richtig, aber vielleicht LNewText oder GetNewText?

AnsiString ??
RawByteString
oder besser noch TBytes bzw. TArray<Byte>
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 17. Mär 2023, 11:03
Ich dachte immer, TMemoryStream kümmert sich nicht um EnCoding.
Das ist Richtig, aber vielleicht LNewText oder GetNewText?

AnsiString ??
RawByteString
oder besser noch TBytes bzw. TArray<Byte>
Ja, ich habe jetzt LNewText als TBytes definiert und weise den string aus GetNewText über LNewText := BytesOf(LMergeField.GetNewText); zu.
Das sollte jetzt wohl, wenn ich euch richtig verstanden habe, die richtige Herangehensweise sein.

Ich habe mir den Feldinhalt des Blobs jetzt vor und nach dem Post in eine Datei schreiben lassen.
Delphi-Quellcode:
  LStream.Clear;
  TBlobField(DM.qryMain.FieldByName('DOKUMENT')).SaveToStream(LStream);
  LStream.SaveToFile('1.rtf');
  DM.qryMain.Post;
  LStream.Clear;
  TBlobField(DM.qryMain.FieldByName('DOKUMENT')).SaveToStream(LStream);
  LStream.SaveToFile('2.rtf');
Das Post ist also die Ursache. Und man sieht am Screenshot, dass das RTF scheinbar "verbessert" wird.
Nach dem Post fehlt schon das "ansi" (im Screenshot markiert).
Ich habe keine Ahnung, was IBObjects da macht.

Ich lade den konvertierten Stream nicht mehr ins BlobField
sondern Stream -> RichEditControl -> Stream -> BlobField.

Damit funktioniert es und das RichEditControl wandelt gleich das Bild in nicht binär um.

Ich hätte gern verstanden, was da schief läuft, aber - was solls...

Danke Happy coding
Danke himitsu
Miniaturansicht angehängter Grafiken
vorher_nachher.jpg  
Frank Reim
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 17. Mär 2023, 11:26
Es gibt auch ein Delphi-Referenz durchsuchenTBytesStream

Vielleicht erkennt die Komponente, wenn ANSI aussreicht und speichert damm im kleinst möglichen Format?


So lange kein Unicode/Umlaute/Sonderzeichen vorkommen, dann reicht es ja aus und wäre auch grundsätzlich egal.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Speichern in BlobField zerschießt MemorySTream

  Alt 17. Mär 2023, 12:33
Wenn man der falschen Fährte folgt und einen Tunnelblick bekommt, sollte man erst mal abschalten.
Das habe ich jetzt gemacht. War eine Stunde laufen...

Und dann war mir klar, dass das Post nicht derartige Änderungen erzeugen kann.
Also musste irgendwie etwas Anderes in das Feld geschrieben werden.
Schön versteckt im Code gab es noch ein Ereignis ausgelöst vom BeforePost des DataSet,
welches den Inhalt des RichTextEditors ins Feld geschrieben hat.

Damit war immer ein leerer RTF - "Rumpf" in der Datenbank.


So, jetzt keine Depression bekommen, kann passieren...

Frank
Frank Reim
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:09 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