Laden...

Stream mit offset lesen

Erstellt von rodgerwilco vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.489 Views
R
rodgerwilco Themenstarter:in
3 Beiträge seit 2017
vor 6 Jahren
Stream mit offset lesen

Hallo zusammen,

ich habe das Problem, dass ich eine Antwort eines Web-Servers verarbeiten möchte und hierbei mit dem Antwortstrom arbeiten muss, welches mich vor ein paar Probleme stellt. Der Antwortstrom besteht aus zwei Teilen. Im ersten Teil werden Meta-Daten als plain-text übertragen und im Anschluss reine Binärdaten. Ich möchte lediglich die Binärdaten herausfiltern und abspeichern. Hier scheine ich aber einen Fehler beim Suchen des Binärteils zu machen. Getrennt wird der plain-Text vom Binärteil durch die Zeichenfolge "!TER". Ein Fehler scheint in der Bestimmung des Position des Endes vom Plain-Text zu legen. Vielleicht ist in der while-Schleife auch noch ein Fehler enthalten.
Es wäre super, wenn mir jemand hierzu etwas Hilfestellung geben könnte.

Danke und Gruß,
rodgerwilco



HttpWebResponse httpWebesponse = (HttpWebResponse)httpWebRequest.GetResponse();

//store data in these files
string strContent = pstrDownloadPfad + pstrDateiname;

//Receive response stream
Stream response = httpWebesponse.GetResponseStream();

//Set up file to store content
try
{
	FileStream fsContent = File.Create(strContent);

	//for reading the response stream
	Byte[] buffer = new Byte[32 * 1024];

	//start reading response
	int read = response.Read(buffer, 0, buffer.Length);

	//search beginning of binary-part
	int intPosByte2 = findByteArray(buffer, Encoding.ASCII.GetBytes("!TER")) + 4; // + 4 da bei ASCII 4 Zeichen 4 Bytes sind	

	//then write content
	read = response.Read(buffer, intPosByte2, buffer.Length - intPosByte2);
	while (read > 0)
	{
		fsContent.Write(buffer, 0, read);
		read = response.Read(buffer, 0, buffer.Length);
	}

	//Close file
	fsContent.Flush();
	fsContent.Close();
	ausgabe("Datei beschafft", 1);
}
catch (IOException e)
{
	ausgabe("Konnte Datei nicht laden bzw. ueberschreiben " + e.ToString(), 1);
}

D
985 Beiträge seit 2014
vor 6 Jahren

Nach dem Lesen des ersten Blocks (3*1024 Bytes) stehen ja am Anfang die unnötigen und am Ende die benötigten Daten.

Allerdings behälst du die unnötigen und überschreibst die benötigten Bytes.

R
rodgerwilco Themenstarter:in
3 Beiträge seit 2017
vor 6 Jahren

Danke für deine Antwort. Von der Theorie her verstehe ich das, aber ich habe Schwierigkeiten, die richtige Stelle im Code zu finden. Kannst du mich eventuell noch etwas mit der Nase draufstubsen.

//start reading response
int read = response.Read(buffer, 0, buffer.Length);

//search beginning of binary-part
int intPosByte2 = findByteArray(buffer, Encoding.ASCII.GetBytes("!TER")) + 4; // + 4 da bei ASCII 4 Zeichen 4 Bytes sind	

//then write content
read = response.Read(buffer, 0, buffer.Length);
while (read > 0)
{
	fsContent.Write(buffer, 0, read);
	read = response.Read(buffer, 0, buffer.Length);
}
D
985 Beiträge seit 2014
vor 6 Jahren

Nun, der Code sieht ja schon wieder anders aus ... aber die Richtung stimmt schon mal 😁


//start reading response
int read = response.Read(buffer, 0, buffer.Length);

// We get f.i.
// ttttttttt!TERbbbbbbb
// read is 20

//search beginning of binary-part
int intPosByte2 = findByteArray(buffer, Encoding.ASCII.GetBytes("!TER")) + 4; // + 4 da bei ASCII 4 Zeichen 4 Bytes sind    

// intPosByte2 is 13
// now write form buffer position intPosReadByte2 (13) the read (20) - intPosReadByte2 (13) (=>7) bytes to the stream

if ( read - intPosByte2 > 0 )
  fsContent.Write(buffer, intPosByte2, read - intPosByte2);

//then read and write content
read = response.Read(buffer, 0, buffer.Length);
while (read > 0)
{
    fsContent.Write(buffer, 0, read);
    read = response.Read(buffer, 0, buffer.Length);
}

Dein Code setzt allerdings auch auf das Prinzip Hoffnung ... das der Trenner !TER auch immer innerhalb des ersten Blocks komplett auftaucht.

Ein einfaches Problem bekommst du, wenn das so aussehen würde


tttttttttttttttttttt
tttt!TERbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbb
bbbbb

und richtig blöd wird es, wenn dieser Trenner genau zwischen zwei Blöcken zu finden ist


tttttttttttttttttt!T
ERbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbb
bbbbb

3.003 Beiträge seit 2006
vor 6 Jahren

Sir Rufo hat ja schon auf die Schwierigkeiten hingewiesen. Um denen zu begegnen:

a) verkleinere den gelesenen Buffer
b) behalt den jeweils zuletzt gelesenen Block
c) bilde aus dem aktuellen und dem zuletzt gelesenen Block einen einzigen und such den Delimiter dort
d) findest du ihn, schreib alles ab dem Delimiter
e) vergrößere den buffer wieder
f) lies und schreib den Rest

LaTino

Außerdem: kleine Schönheitskorrektur


//statt:
read = response.Read(buffer, 0, buffer.Length);
while (read > 0)
{
    fsContent.Write(buffer, 0, read);
    read = response.Read(buffer, 0, buffer.Length);
}
//das hier:
while((read = response.Read(buffer, 0, buffer.Length)) > 0)
    fsContent.Write(buffer, 0, read);

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

R
rodgerwilco Themenstarter:in
3 Beiträge seit 2017
vor 6 Jahren

Danke an euch für die Hilfe. Die aufgezeigt Problematik war mir gar nicht so bewusst, aber stimmt natürlich. Ich schaue mal, ob ich es noch etwas zuverlässiger hinbekomme.

mfg
Rodgerwilco