Ein Stream zwischenspeichern

12. September 2007 22:30

Hallo zusammen!

Es soll ein Stream, das von einer Message aus der MSMQ kommt, durch ein XMLPort ins System eingelesen werden. Es gibt aber Fälle wo eine Message einfach leer sein kann. Deswegen möchte ich vorher die Länge des Streams bestimmen. Wenn also Länge > 0 dann den Stream mit XMLPort einlesen.
Das Problem dabei ist - wenn man den Stream liest dann wird es auch automatisch geleert, es muss also zwischengespeichert werden. Wie kann ich den Stream zwischenspeichern und wiederherstellen?

Code:
ComCom::MessageReceived(VAR InMessage : Automation "''.IDISPATCH")
InMsg := InMessage;
InStr := InMsg.GetStream();
//InStream sichern
//Länge von InStream bestimmen (z.B. in der Schleife)
//Wenn Streamlänge > 0 dann wiederherstellen und mit XMLPort einlesen


Wenn ich versuche, wie folgt, zwischen zu speichern dann hängt sich der Client auf :evil:
Code:
TempXMLRec."XML Request".CREATEOUTSTREAM(TempOutStr);
COPYSTREAM(TempOutStr, InStr);  //<----Hier steht alles

InStr.READTEXT(char);
IF InStr.EOS THEN
  ret := TRUE
ELSE
  ret := FALSE;

TempXMLData."XML Request".CREATEINSTREAM(InStr);

13. September 2007 09:53

Hi,

den Befehl COPYSTREAM habe ich bis jetzt noch nicht gebraucht. Von daher kenne ich mich mit den Fehlern damit nicht so aus. Besteht das Problem auch beim Kopieren von kleinen Streams?

Kannst du bitte im Code noch die Variablendeklarationen angeben?


Gruesse
feri

13. September 2007 09:59

Code:
--Variablen--
ComCom   : Automation :   'Navision Communication Component version 2'.CommunicationComponent   
InStr   : InStream
--Variablen--

ComCom::MessageReceived(VAR InMessage : Automation "''.IDISPATCH")
InMsg := InMessage;
InStr := InMsg.GetStream();
//InStream sichern
//Länge von InStream bestimmen (z.B. in der Schleife)
//Wenn Streamlänge > 0 dann wiederherstellen und mit XMLPort einlesen


Wenn ich versuche, wie folgt, zwischen zu speichern dann hängt sich der Client auf :evil:
Code:
--Variablen--
TempXMLRec : Record : "XML Data"
TempOutStr  : OutStream
char : Text : 1
--Variablen--

IsStringEmpty(InStr : InStream) ret : Boolean
TempXMLRec."XML Request".CREATEOUTSTREAM(TempOutStr);
COPYSTREAM(TempOutStr, InStr);  //<----Hier steht alles

InStr.READTEXT(char);
IF InStr.EOS THEN
  ret := TRUE
ELSE
  ret := FALSE;

TempXMLData."XML Request".CREATEINSTREAM(InStr);
Zuletzt geändert von f.ritz am 13. September 2007 17:38, insgesamt 1-mal geändert.

13. September 2007 17:36

Hi,

ich vermute InStr = InStreamQueue?
Stehst du bei der Tabelle TempXMLRec auf einem neuen bzw. bestehenden Datensatz oder irgendwo im Leeren?

Ist diese Tabelle "Temporary"?

Gruesse
feri

13. September 2007 17:43

Zum 1. : InStr = InStreamQueue - mein Fehler! Ist korregiert!
Zum 2. : Beim TempXMLRec steh ich auf einen neuen Datensatz
Zum 3. : Diese Tabelle ist nicht "Temporary" (ich weiß - schlechte Variablenbenennung).

Aber wie gesagt, auf dem COPYSTREAM(InStr, OutStr)-Befehl hängt sich alles auf!

17. September 2007 08:04

Hi,

ich habe das jetzt bei mir im System kurz getestet.

Code:
Name          DataType   Subtype   Length
file1         File      
DescStati     Record     DescStati   

file1.OPEN('D:\test.txt');
file1.CREATEINSTREAM(InStrm);

DescStati.RESET();
DescStati.INIT();
DescStati.Type := 'Type';
DescStati.Code := 'Code';
DescStati.INSERT();
DescStati."XML File".CREATEOUTSTREAM(OutStrm);

IF COPYSTREAM(OutStrm,InStrm) THEN begin
  DescStati.MODIFY();
  MESSAGE('ok');
END;


Hier wird ein txt File ausgelesen und in die Tabelle DescStati geschrieben. Getestet habe ich das bis zu einer Datei-Groesse von ~50MB.

Was mir noch einfaellt: Gibst du zufaellig einen Stream als Parameter von einem anderen Objekt mit? Da hatte ich auch schon einige Probleme. Innerhalb von einem Objekt klappt das wunderbar, aber mit mehreren Objekten kommt er irgendwie durcheinander :-?

Gruesse
feri