Announcement

Collapse
No announcement yet.

Stream, Blob und InterBase6

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stream, Blob und InterBase6

    Hallo,

    Folgendes Problem (Delphi5 Prof., IBX4.52, IB 6.0):
    Ich habe aus einem Messgerät einen STRING ausgelesen. Dieser STRING enthält einen Kopf und Daten in INT32 form. Wenn ich den STRING in meine DB als STRING speichern will erhalte ich einen CharacterSet Fehler. Jetzt habe ich ein Blob-Feld daraus gemacht, komme aber mit den TIBBlobStream überhaupt nicht zurecht. Ich möchte den STRING einfach in mein DB-Feld MESSWERT übergeben. Die DB-Tabelle heist SAVEMESS. Außerdem muss ich später den BLOB aus der DB wieder auslesen und in einen "normalen" STRING umwandeln.<br>
    Ich verwende für den Zugriff auf die DB:<br>
    TIBDataBase, TIBTrasaction und TIBDataSet<br>

    Das Ein- und Auslesen aller anderen Daten ist OK. Die netten Hilfen von Delphi haben bei mir leider keine "Wirkung".

    Danke Walter

  • #2
    1. Der CharacterSet Fehler kann dadurch resultieren, dass du das
    falsche characterset benutzt. Pruefe mal den Inhalt von deinen Daten
    (Umlaute Sonderzeichen etc.)
    Ich benutze meist das CharSet ISO8859_1, das auch umlaute kann.

    2. Zu den BlobStreams
    Ich hatte auch Schwierigkeiten mit den TIBBlobStreams und benutze
    einen Memorystream.
    Hier ein kleines Code-Beispiel mit dem ich ein Richedit in ein Blob
    speichere.

    procedure TDM1.TextBausteinEintragen;
    var
    astream: TMemoryStream;
    begin
    try
    astream := TMemoryStream.Create;
    FormNeuerTextBaustein.Editor.Lines.SaveToStream(as tream); //Editor ist eine Instanz von TRichEdit

    if IBTransKarte.InTransaction then
    IBTransKarte.Rollback;

    IBTransKarte.StartTransaction;
    try

    IBQueryInsertTextBaustein.ParamByName('BEARBEITER' ).asString :=
    dma.GetCurrentUserName;
    IBQueryInsertTextBaustein.ParamByName('KUERZEL').a sString :=
    FormNeuerTextBaustein.EditTextBezeichnung.Text;
    IBQueryInsertTextBaustein.ParamByName('TEXT').Load FromStream(aStream,
    ftBlob); // hier wird der BlobInhalt gespeichert

    IBQueryInsertTextBaustein.ExecSQL;

    IBTransKarte.Commit;
    except
    IBTransKarte.Rollback;
    end; //try
    finally
    astream.Free;
    end; //try

    end; // Proc

    //************************************************** *****//
    // Die IBQueryInsertTextBaustein:
    //
    // insert into TEXTBAUSTEIN ( KUERZEL, BEARBEITER, TEXT)
    // Values (:Kuerzel, :bearbeiter, :text)
    //************************************************** *****/

    Comment


    • #3
      Hallo Rudi Neuss,

      zu 1:<br>
      Mein STRING hat keine "normalen" Zeichen, er enthält einen Header der 6 Zeichen lang ist (#41600) und dann nur noch 32Bit Integer-Werte., d. h. es gibt kein passendes characterset.

      zu 2:<br>
      Ich habe versucht Dein Beispiel umzusetzen, habe aber immer noch nicht verstanden wie ich meinen STRING dem BLOBSTREAM zuweisen kann. Ich benutze ja kein RichText oder ähnliches.<br>
      Hier mein Projektauszug:

      Procedure xyz .....<br>
      var<br>
      blobwert : TMermoryStream;<br>
      tprec.messwert : string; //TPREC ist ein Record und Messwert ist ein STRING im Record<br>
      begin<br>
      .... //einige vorbereitungen<br>
      blobwert := TMemoryStream.Create;<br>
      blobwert:=tprec.messwert (hier ist mein Problem, wie geht das?)<br>
      .....<br>

      Vielen Dank und Grüße Walte

      Comment


      • #4
        Moin Walter,<br>vor einiger Zeit habe ich mir mal folgende Unit zur Löung des Problem erstellt:<br>
        <pre><font size="1" face="Verdana">
        unit Streaming;

        interface

        uses Sysutils, Classes;

        Type

        TMemoryStreamExt = class(TMemoryStream)
        public
        procedure WriteStringToStream(aStr : String);
        function ReadStringFromStream : String;
        end;

        TFileStreamExt = class(TFilestream)
        public
        procedure WriteStringToStream(aStr : String);
        function ReadStringFromStream : String;
        end;

        implementation

        { TFileStreamExt }

        procedure TFileStreamExt.WriteStringToStream(aStr : String);
        var
        aStrLen : Integer;
        begin
        aStrLen:=Length(aStr);
        WriteBuffer(aStrLen,SizeOf(Integer));
        WriteBuffer(Pointer(aStr)^,aStrLen);
        end;

        function TFileStreamExt.ReadStringFromStream: String;
        var
        aStrLen : Integer;
        begin
        ReadBuffer(aStrLen,SizeOf(Integer));
        SetLength(Result,aStrLen);
        ReadBuffer(Pointer(Result)^,aStrLen);
        end;

        { TMemoryStreamExt }

        function TMemoryStreamExt.ReadStringFromStream: String;
        var
        aStrLen : Integer;
        begin
        ReadBuffer(aStrLen,SizeOf(Integer)); // Länge des Strings lesen
        SetLength(Result,aStrLen); // aStrLen auf diese Länge setzen
        ReadBuffer(Pointer(Result)^,aStrLen); // String lesen
        end;

        procedure TMemoryStreamExt.WriteStringToStream(aStr: String);
        var
        aStrLen : Integer;
        begin
        aStrLen:=Length(aStr);
        WriteBuffer(aStrLen,SizeOf(Integer)); //Länge des Strings schreiben
        WriteBuffer(Pointer(aStr)^,aStrLen); // String schreiben
        end;

        end.
        </font></pre>
        <br>Jens Schuman

        Comment


        • #5
          Hallo,

          erst mal Danke Jens für Deine schnelle Antwort!
          Leider bin ich zu scheinbar blöd das mit den Stream's zu verstehen, oder ist es wirklich so schwer?<br>
          Hier beschreibe ich nochmal mein Problem:<br>
          Ich lese Daten von einem Spektrumanalyser über die serielle Schnittstelle ein. Die eingelesenen Daten speichere ich in einem Record als String (TPREC.MESSWERT). Der Inhalt des STRING sieht folgendermassen aus:<br>
          #41600....und es folgen unleserliche Zeichen (32 Bit INTEGER-Werte)

          Diesen STRING will ich irgend wie in meine InterBase 6 Datenbank ein- und später auch wieder auslesen können, und den STRING wieder im obgen Format zur Verfügung haben. Die Datenbank weigert sich aber diesen STRING als String zu übernehmen (Fehlermeldung:falsches caracterset), was mir logisch ist, da die 32Bit-Werte nicht als Zeichen dargestellt werden können. Ich arbeite mit den IBX-Komponenten IBDataBase, IBTransaction und IBDataSet.

          Die meisten Delphi-Hilfen und Forumbeiträge sind entweder auf Text-String's oder auf Grafiken ausgelgt. Auch die Handbücher und die Bücher von Herrn Kosch behandeln das Thema BLOB's kaum.

          Vieleicht kann mir jemand einen Weg vorschlagen oder ein Beispiel für diese "Transaktionen" zur Verfügung stellen.

          Vielen Dank Walte

          Comment


          • #6
            Hallo,

            in meinem Buch <i>InterBase Datenbankentwicklung mit Delphi</i> ist auf der Seite 365 ein Beispiel zu finden, wie eine als Objekt verpackte <b>Record</b>-Instanz in einer BLOb-Spalte des InterBase gespeichert und wieder ausgelesen wird. Anstelle die Messwerte (Zahlen) in einen String zu quetschen, würde ich die 32-Bit-Interwerte doch gleich als Objektinstanz speichern:
            <pre>
            BS := IBDataSet1.CreateBlobStream(IBDataSet1DATA, bmWrite);
            try
            BS.WriteComponent(SR);
            IBDataSet1.Post;
            finally
            BS.Destroy;
            end;
            </pre>
            Über <b>WriteComponent</b> schiebt man die Aufgabe des Übersetzens der Objektinstanz in die BLOb-Daten auf Delphi ab, zumal mit <b>ReadComponent</b> auch der automatische Rückweg angeboten wird.

            P.S: Beim Thema BLObs werden Grafiken gerne in den Beispielen verwendet, weil man sofort eine visuelle Rückmeldung über Erfolg/Misserfolg erhält :-

            Comment


            • #7
              Hallo,

              ich habe noch weitere Fragen:

              1. Wie wandle ich meinen String "manu.tprec.messwert" in ein Streamobjekt um (und auch wieder zurück), das konnte ich weder aus dem Buch, noch aus den hier aufgezeigten Beispielen erkennen. Bei meiner Codezeile "blobwert.WriteComponent(manu.tprec.messwert); " will der Compiler ein Object und keinen String sehen.

              2. Wenn ich das Beispiel aus dem Buch versuche umzusetzen bekomme ich
              bereits bei der Zeile "blobwert:=dbmod.ibds_sm_save.CreateBlobStream(dbm od.ibds_sm_saveMESSWERT, bmWrite);" die Fehlermeldung "Undefinierter Bezeichner bmWrite"<br>
              Hier folgt meine Procedure:

              procedure Tfrm_save.bbt_msaveClick(Sender: TObject);<br>
              var swert, fname : string; i : integer; <B>blobwert : TStream;</B> <br>
              begin<br>
              if MessageDlg('Möchten Sie die Messung wirklich speichern ?'<br>
              , mtConfirmation, [mbYes, mbNo], 0) = mrYes then<br>
              begin<br>
              repeat<br>
              swert:= InputBox('Messung Speichern',<br>
              'Eine Beschreibung eingeben.Max.40 Zeichen','');<br>
              until length(swert)<=40;<br>
              swert:=swert+' '+DateToStr(Date)+','+TimeToStr(Time);<br>
              dbmod.ibdb_savemess.Open;<br>
              dbmod.ibt_savemess.StartTransaction;<br>
              dbmod.ibds_sm_save.Active:=true;<br>
              dbmod.ibds_sm_save.Append;<br>
              dbmod.ibds_sm_saveNAME.Value:=swert;<br>
              dbmod.ibds_sm_saveCF.Value:=manu.tprec.cf/1000000;<br>
              ........<br>
              dbmod.ibds_sm_saveDATERF.Value:=manu.daterf;<br>
              dbmod.ibds_sm_saveBEM.Value:=manu.bem;<br>
              <B> blobwert:=dbmod.ibds_sm_save.CreateBlobStream(dbmo d.ibds_sm_saveMESSWERT, bmWrite);<br>
              blobwert.WriteComponent(manu.tprec.messwert);</B><br>
              dbmod.ibds_sm_save.Post;<br>
              dbmod.ibds_sm_save.Active:=false;<br>
              dbmod.ibt_savemess.Commit;<br>
              dbmod.ibdb_savemess.Close;<br>
              end;<br>
              end;<br>

              Vielen Dank für die von Euch bereits geleistete Hilfe!

              Viele Grüße Walte

              Comment


              • #8
                Hallo,

                Ihr Fehler besteht darin, als Zahlen vorliegende Messwerte in einen String abzulegen (wo diese überhaupt nicht hingehören). Warum müssen diese Nicht-String-Daten unbedingt in einem String abgelegt werden? Sie schreiben in Ihrer Frage "<i>Dieser STRING enthält einen Kopf und Daten in INT32 form</i>" - also handelt es sich um einen <b>Record</b> (besteht als mehrere Feldern) und nicht um einen String. Und in meinem Buch speichere ich im o.g. Beispielprojekt auch einen Record, der als Objekt verpackt wird.

                Wie sieht der Inhalt Ihres "Strings" in einem Beispiel aus, wenn das Veto <i>CharacterSet-Fehler</i> kommt. Was zeigt ein MessageBox-Aufruf als Text an

                Comment


                • #9
                  Hallo Herr Kosch,

                  Die Daten im String werden folgendermaßen eingelesen:<br>

                  Die Komponente ist CPort(Lib), meine Form "MANU".<br>
                  com_1.WriteStr(':trac:data? TRACE1'+chr(10));// Sagt dem Analyser das er die Grafikdaten liefern soll<br>
                  repeat // mit dieser Schleife prüfe ich ob alle Daten anliegen<br>
                  rdcount:=com_1.InputCount;<br>
                  edit1.Text:=inttostr(rdcount);<br>
                  application.ProcessMessages;<br>
                  until rdcount>=1611;<br>
                  com_1.ReadStr(rdwert,rdcount); //hier werden die Daten über Com1 eingelesen "RDWERT" ist ein String "RDCOUNT" ist Integer, ist von CPort so vorgegeben!<br>
                  tprec.messwert:=rdwert; //ab hier wandle ich die Stringdaten in Messwerte um<br>
                  i:=1;<br>
                  j:=1;<br>
                  k:=0;<br>
                  while i <= 1604 do //401 Messwerte a 4 Byte = 1604<br>
                  begin<br>
                  if j<=4 then // 4 Byte abfragen<br>
                  begin<br>
                  cwert:=rdwert[i+6]; // den Header auslassen<br>
                  case j of // Messwert errechnen<br>
                  1 : lwert:=ord(cwert)*16777216;<br>
                  2 : lwert:=lwert+(ord(cwert)*65536);<br>
                  3 : lwert:=lwert+(ord(cwert)*256);<br>
                  4 : lwert:=lwert+ord(cwert);<br>
                  end;<br>
                  inc(j);<br>
                  end;<br>
                  if j=5 then<br>
                  begin<br>
                  k:=k+1;<br>
                  tprec.trace[k]:=lwert/1000; // den Messwert ins Array eintragen<br>
                  j:=1;<br>
                  end;<br>

                  Im hier folgenden Aufruf sehe ich als Text meinen String wie weiter unten dargestellt.<br>
                  if MessageDlg(rdwert, mtConfirmation, [mbYes, mbNo], 0) = mrYes then<br>
                  begin<br>
                  ;<br>
                  end;<br>

                  Jetzt kommt der String, der so von der seriellen Schnittstelle eingelesen wird (dürfte Ihnen vieleicht bekannt vorkommen war mal eine Frage im Forum von mir):

                  rdwert: '#41604ÿþÌ'#$1E'ÿþÆ–ÿþÁ±ÿþÎFÿþÆØÿþ¿eÿþÈóÿþË5ÿþÐpÿþ É)ÿþÂ…ÿþÔÔÿþÆ^ÿþÑñÿþÉVÿþÉ'#$1A'ÿþÒ&ÿþÉbÿþÎ!ÿþÐ'#8' ÿþÊ–ÿþÐ'#5'ÿþ·ÿþÒ¦ÿþѾÿþÊoÿþ̆ÿþÑlÿþË(ÿþÏnÿþÖ"ÿþÍ ÝÿþÌ'#$B'ÿþÀ¡ÿþÅšÿþÎúÿþØÀÿþÈžÿþÃ'#$16'ÿþÉ/ÿþÂ'#8'ÿþÓæÿþϧÿþÐ1ÿþÒ”ÿþË-ÿþÌùÿþËÿþÒŸÿþÅ7ÿþÈLÿþÐ2ÿþίÿþÈÛÿþÈ-ÿþÉ9ÿþÒÒÿþ¾3ÿþÝ"ÿþÊwÿþÑLÿþÍÛÿþÌ2ÿþΡÿþÊÜÿþÌ'#8'ÿþÍ '#$19'ÿþËÑÿþÄ£ÿþÉ»ÿþÉDÿþÍìÿþÉ_ÿþÆ'#$10'ÿþÚÝÿþË>ÿþÌ „ÿþÎ#ÿþÇ'#$1B'ÿþÎ'#$D'ÿþÊœÿþÇËÿþÏ‹ÿþËcÿþÌžÿþÖzÿþ̈ ÿþÇÞÿþÐ|ÿþÅÙÿþÚlÿþÌhÿþÂbÿþÃìÿþÑ=ÿþÎVÿþÎÞÿþÏ'#$1A'ÿ þÑÏÿþÓTÿþÉKÿþÉ'#1'ÿþÐDÿþÍ'#5'ÿþÎÐÿþÒmÿþÃëÿþÇÏÿþÊ}ÿ þÐtÿþÐ{ÿþËêÿþËEÿþÉ'#$D'ÿþÏÿþÆ»ÿþÆœÿþÇöÿþÍ*ÿþÒÄÿþÈ òÿþÎ*ÿþƈÿþÓ'#4'ÿþËšÿþÈ'#$17'ÿþ̆ÿþÈ<ÿþÊêÿþÉ'#2'ÿþ ¿½ÿþПÿþÏoÿþÆðÿþ¸þÿþÓ'#$1B'ÿþÔAÿþÊ.ÿþÊ'#3'ÿþÙ„ÿþÓk ÿþÍñÿþÈ'#$1F'ÿþÍ‘ÿþÉÁÿþÊÿþÍ_ÿþÅuÿþÏ—ÿþÊÖÿþÈïÿþÌPÿ þÐ|ÿþÃ'#$B'ÿþÊîÿþΣÿþÈÜÿþλÿþÅŽÿþÈóÿþÉ,ÿþÈÐÿþÚ'#$1 4'ÿþÇäÿþÇaÿþ½ëÿþÌ'#1'ÿþLjÿþÈÎÿþÒ'#7'ÿþÌ'#2'ÿþÊRÿþÌ _ÿþÑÅÿþÏéÿþÌÿþÉîÿþÍ“ÿþÔmÿþÏ©ÿþÄuÿþÐÿþ˹ÿþÏõÿþÓwÿ þÃ¥ÿþÔ\ÿþÉïÿþͺÿþÑJÿþÍKÿþÇtÿþÈ€ÿþÑÐÿþÅ[ÿþÐLÿþË'#$1F'ÿþË|ÿþ̦ÿþË2ÿþÎÓÿþÓ÷ÿþÊXÿþÇûÿþÂlÿþÅÀÿ þÃXÿþË;ÿþÊQÿþÌoÿþÍÆÿþÏ'#8'ÿþÄfÿþÈxÿþÑ·ÿþÏ'ÿþɉÿþÎI ÿþÆ5ÿþÇ'#$15'ÿþÊ!ÿþÌåÿþÃãÿþÂsÿþÍ'#$D'ÿþÐÅÿþÆ'#5'ÿþ Ê»ÿþÅWÿþÉÿþÓèÿþÂXÿþÇîÿþËŸÿþÊ6ÿþÇ{ÿþÏaÿþÖaÿþÇbÿþ¼É ÿþÈ+ÿþÏ'#$13'ÿþÐ'#$15'ÿþÅ[ÿþÕÿþÇvÿþÆ#ÿþÐþÿþÕÅÿþÄfÿþÒ¥ÿþÐÆÿþÃ:ÿþÊ!ÿþÎÖÿþÏOÿþ ÆÿÿþÊõÿþËuÿþ¿AÿþЬÿþÑÓÿþËÿþÊîÿþÉ=ÿþÊøÿþÃ(ÿþÖMÿþÊ‹ ÿþÌäÿþÀ¤ÿþËXÿþÊäÿþÒKÿþάÿþÄôÿþÔ"ÿþËJÿþÁ'#6'ÿþËNÿþÏ )ÿþÈDÿþÈ=ÿþÍ,ÿþÅNÿþËŠÿþÅÃÿþÍÖÿþÒ'#$1B'ÿþÒ`ÿþÏÒÿþǼ ÿþɘÿþ¼¼ÿþÍØÿþÇðÿþÞ'#$12'ÿþËÐÿþÈ|ÿþÏhÿþɲÿþÌ^ÿþÉ.ÿ þÒeÿþËEÿþÑ'#$18'ÿþÁ>ÿþÍ'#$E'ÿþÑBÿþĈÿþÓ»ÿþÏZÿþÇÏÿþ ÉbÿþÑ'#$15'ÿþÔôÿþÉjÿþÏXÿþÌœÿþÉ_ÿþÕçÿþΔÿþÈøÿþÉîÿþÌ '#$12'ÿþÓÕÿþÏ~ÿþÕ|ÿþÐ^ÿþÉNÿþÅòÿþÓžÿþÈmÿþÑ4ÿþÎ'#8'ÿ þÑ÷ÿþÇ(ÿþÅ\ÿþÎÃÿþÖÉÿþÏ÷ÿþÉïÿþÕÁÿþÆáÿþË'#3'ÿþÍöÿþɼ ÿþÕ‹ÿþÃWÿþÍyÿþÊ/ÿþÅ‹ÿþÒeÿþÆUÿþÄÑÿþÇ'#4'ÿþÇ]ÿþÎöÿþÒeÿþÑ'#0'ÿþÉ—ÿþÃâÿþÓEÿþ̇ÿþÎîÿþÊØÿþÐ9ÿþÅÇÿþÌ îÿþÀÖÿþÊÈÿþϼÿþÊKÿþÇ\ÿþÁ'#$E'ÿþ½yÿþÂ*ÿþÃRÿþÒWÿþÖZÿ þɵÿþÄÓÿþÏòÿþÚöÿþÌ¥ÿþÇ¡ÿþÌÄÿþÍ,ÿþÓmÿþÒ`ÿþÆËÿþÉ'#4' ÿþÑéÿþÉöÿþÊ+ÿþÏßÿþÐéÿþÊ.ÿþÌ'#$17'ÿþÇïÿþÒ—'#$A'

                  String Erläuterung:<br>
                  # // beginn des Header<br>
                  41604 //4 = Teiler 1604 = anzahl der folgenden Bytes (INT32 = 4 Byte) also 1604:4=401 Messwerte<br>
                  Rest = Bytes

                  Danke und Grüße Walte

                  Comment


                  • #10
                    Hallo Walter,<br>Herr Kosch meint, das Du den String, der ja scheinbar in einem Record gespeichert wird anstatt in diesen Record in ein Object speicherst. Dafür mußt Du Dir nein Object deklarieren !!!
                    Dieses Objekt muß von TComponent abstammen. Dann kann über WriteComponent auf das delphiinterne Streaming zurückgriffen werden, und Du mußt Dich um die Speicherung nicht kümmern. <br>Beispiel:<br>
                    <pre><font size="1" face="Verdana">
                    unit Unit2;

                    interface

                    uses SysUtils, Classes;

                    Type
                    // !!! Dies ist der Recordersatz !!!
                    TMesswerte = class(TComponent)
                    private
                    FWert1: Integer;
                    FWert3: Integer;
                    FWert2: Integer;
                    public
                    procedure Assign(Source : TPersitent); override;
                    published // Wichtig: die Werte müssen published sein, wenn nicht, werden sie nicht vom Streaming erfasst !!!
                    property Wert1 : Integer read FWert1 write FWert1;
                    property Wert2 : Integer read FWert2 write FWert2;
                    property Wert3 : Integer read FWert3 write FWert3;
                    end;
                    implementation

                    { TMesswerte }

                    procedure TMesswerte.Assign(Source: TPersitent);
                    begin
                    If Source is TMesswerte then
                    begin
                    FWert1:=TMesswerte(Source).Wert1;
                    FWert2:=TMesswerte(Source).Wert2;
                    FWert3:=TMesswerte(Source).Wert3;
                    end
                    else
                    inherited Assign(Source);
                    end;

                    //Speichern des Objektes
                    var
                    Messwerte : TMesswerte;
                    ...
                    Messwerte:=TMesswerte.Create(Nil);
                    Try
                    With Messwerte do
                    begin
                    Wert1:=Messwert1; // Messwert1 bis 3 ist das, was Du vom Messgerät erhälst
                    Wert2:=Messwert2;
                    Wert3:=Messwert2;
                    end;
                    // Jetzt die Schose in den Blobstream
                    ...
                    blobwert:=dbmod.ibds_sm_save.CreateBlobStream(dbmo d.ibds_sm_saveMESSWERT, bmWrite);
                    blobwert.WriteComponent(Messwerte);
                    ...
                    Finally
                    Messwerte.Free;
                    end;
                    ...

                    //Lesen des Objektes
                    var
                    Messwerte : TMesswerte;
                    ...
                    Messwerte:=TMesswerte.Create(Nil);
                    Try
                    // Jetzt die Schose iaus dem Blobstream
                    ...
                    blobwert:=dbmod.ibds_sm_save.CreateBlobStream(dbmo d.ibds_sm_saveMESSWERT, bmRead);
                    blobwert.ReadComponent(Messwerte);
                    ...
                    Finally
                    Messwerte.Free;
                    end;
                    ...
                    </font></pre>
                    <br>So ungefähr sollte es klappen<br>Jens Schuman

                    Comment


                    • #11
                      Hallo,

                      wie der Inhalt von <i>rdwert</i> zeigt, handelt es sich <b>nicht</b> um einen String, sondern um binäre Daten, die u.a. in einer Stringvariablen untergebracht werden können. Ein AnsiString ist für Delphi nur ein 32-Bit-Zeiger auf einen Speicherbereich, in dem man alles Mögliche ablegen kann. So freizügig ist der InterBase jedoch nicht, dort wird schon bei BLOb-Daten ein Unterschied gemacht.

                      Es gibt also 2 Möglichkeiten: <br>
                      1. Daten nicht als String, sondern als binäre BLOb-Daten speichern (wie bei einer Grafik) <br>
                      2. Record als Komponente verpacken und über WriteComponent/ReadComponent konvertiere

                      Comment


                      • #12
                        Hallo,

                        Erst mal Danke, ich glaube es endlich umsetzten zu können!

                        Ich melde mich wieder wenn ich es ausprobiert habe.

                        Gruß Walte

                        Comment


                        • #13
                          Hallo Jens Schumann,

                          eine Frage:
                          Bei deiner Unit2 verwendest Du einzelne Integer-Felder für die Messwerte, geht das auch mit einem ARRAY of INTEGER, ich habe 401 Messwerte zu speichern, und wie muss ich dann den PUBLISHED- und den IMPLEMENTATION-Teil abändern. Der Rest wäre klar.

                          Danke und viele Grüße Walte

                          Comment


                          • #14
                            Hallo Walter,<br>anstatt des Array's könntest Du die Messwerte in einer Kombination aus TCollection und TCollectionItem speichern. Dazu findest Du hier im Forum einige Beispiele. Ich denke aber, das der Verwaltungs-Overhead in bezug auf den zu speichernden Wert ziemlich groß ist. Deshalb schalge ich vor die Integer Werte direkt in den BlobStream zu schreiben. Siehe Vorschlag 1 von Herrn Kosch. Da Integers im Vergleich zu Strings eine konstante Größe haben, ist das auch nicht weiter schwierig.<br>Der Source hier zeigt, wie man Integers in einen Stream schreibt und ließt. Beim lesen werden die Streamdaten in eine dyn Array geschrieben.<br>
                            <pre><font size="1" face="Verdana">
                            unit Unit1;

                            interface

                            uses
                            Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
                            StdCtrls;

                            type
                            TForm1 = class(TForm)
                            ListBox1: TListBox;
                            btnWrite: TButton;
                            btnGet: TButton;
                            procedure FormCreate(Sender: TObject);
                            procedure FormDestroy(Sender: TObject);
                            procedure btnWriteClick(Sender: TObject);
                            procedure btnGetClick(Sender: TObject);
                            private
                            { Private-Deklarationen }
                            FMStream : TMemoryStream; // kann durch TBlobStream ersetzt werden
                            public
                            { Public-Deklarationen }
                            end;

                            var
                            Form1: TForm1;

                            implementation

                            {$R *.DFM}

                            { TForm1 }

                            procedure TForm1.FormCreate(Sender: TObject);
                            begin
                            FMStream:=TMemoryStream.Create;
                            end;

                            procedure TForm1.FormDestroy(Sender: TObject);
                            begin
                            FMStream.Free;
                            end;

                            procedure TForm1.btnWriteClick(Sender: TObject);
                            var
                            iCnt : Integer;
                            Value : Integer;
                            begin
                            FMStream.Clear;
                            For iCnt:=0 to Listbox1.Items.Count-1 do
                            begin
                            Value:=StrToInt(Listbox1.Items[iCnt]);
                            FMStream.Write(Value,SizeOf(Integer));
                            end;
                            end;

                            procedure TForm1.btnGetClick(Sender: TObject);
                            var
                            aInt : Array of Integer;
                            Value : Integer;
                            iCnt : Integer;
                            begin
                            iCnt:=0;
                            Listbox1.Clear;
                            SetLength(aInt,FMStream.Size div SizeOf(Integer)); // Array-Größe berechnen
                            FMStream.Seek(0,soFromBeginning);
                            While FMStream.Read(Value,SizeOf(Integer))&gt;0 do
                            begin
                            aInt[iCnt]:=Value;
                            Inc(iCnt);
                            end;
                            For iCnt:=0 to High(aInt) do
                            Listbox1.Items.Add(IntToStr(aInt[iCnt]));
                            aInt:=Nil;
                            end;

                            end.

                            // Formular Datei
                            object Form1: TForm1
                            Left = 359
                            Top = 218
                            Width = 176
                            Height = 212
                            Caption = 'Form1'
                            Color = clBtnFace
                            Font.Charset = DEFAULT_CHARSET
                            Font.Color = clWindowText
                            Font.Height = -11
                            Font.Name = 'MS Sans Serif'
                            Font.Style = []
                            OldCreateOrder = False
                            OnCreate = FormCreate
                            OnDestroy = FormDestroy
                            PixelsPerInch = 96
                            TextHeight = 13
                            object ListBox1: TListBox
                            Left = 12
                            Top = 12
                            Width = 49
                            Height = 165
                            ItemHeight = 13
                            Items.Strings = (
                            '2314'
                            '3566'
                            '23'
                            '2355'
                            '3455'
                            '3445'
                            '9976'
                            '42'
                            '645'
                            '657'
                            '0'
                            '4546')
                            TabOrder = 0
                            end
                            object btnWrite: TButton
                            Left = 68
                            Top = 16
                            Width = 75
                            Height = 25
                            Caption = 'Write'
                            TabOrder = 1
                            OnClick = btnWriteClick
                            end
                            object btnGet: TButton
                            Left = 68
                            Top = 48
                            Width = 75
                            Height = 25
                            Caption = 'Get'
                            TabOrder = 2
                            OnClick = btnGetClick
                            end
                            end
                            </font></pre><br>Jens Schuman

                            Comment


                            • #15
                              Hallo,<br>
                              <br>
                              Ich habe eine Komponente entwickelt, mit der Streams und sogar Dateien beliebiger grösse sich in einer Interbase-Datenbank speichern lassen. Diese Komponente ist Freeware und unter www.mmvisual.de > Delphi zu Downloaden.<br>
                              <br>
                              Gruss Markus Müller<br&gt

                              Comment

                              Working...
                              X