Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: aus datenblöcken bestimmte Daten filtern

  Alt 28. Feb 2007, 13:20
Zitat von BBoy:
Hier mal der Code wie ich derzeit die Daten extrahiere:
Delphi-Quellcode:
      Anfang := pos('%ANFANG',data);
      Ende := pos('%ENDE',data);
      // wenn keine daten im paket
      if (anfang = 0) and (ende = 0) and (parts = false) then
         exit;
Ich denke hier wäre es besser, wenn Du den Vergleich auf < 1 statt = 0 setzt. So funktioniert das natürlich immer, aber es geht halt auch allgemeiner (falls sich mal die Pos-Funktion ändert), aber weniger wichtig!

Zitat von BBoy:
Delphi-Quellcode:
  // wenn part angefangen wurde aber noch kein ende (also mitte)
  if (anfang=0) and (ende=0) and (parts=true) then begin
    dataParts := dataparts + copy(data,0,TCPDataLength);
  end;
Hier wäre ein else if eindeutiger. Immerhin schließt der erste Fall die folgenden aus, diese müssen dann nicht mehr betrachtet werden. Mit else lässt sich dies dann auch leichter lesen! Zudem kannst Du dann die Bedingung (anfang = 0) rauslassen, da parts=true und ende=0 schon implizieren, dass Du Dich in der Mitte befindest.

Zitat von BBoy:
Delphi-Quellcode:
  // wenn part angefangen wurde und nun das ende da ist
  if (anfang=0) and (ende<>0) and (parts=true) then begin
    dataParts := dataparts + copy(data,0,ende+6);
    parts := false;
    allparts := allparts + dataparts;
    memo3.Lines.Add(allparts);
  end;
Ja, hier nochmal ein else if verwenden. Erspart halt wenn Fall 1 eintritt gleich zwei unnötige Vergleiche! Zudem solltest Du auf Ende > 0 prüfen, da dies eindeutiger für ein Positives vorkommen ist. Gibt Pos irgendwann mal -1 zurück, wäre klar, dass der SubString nicht im String ist, Deine Routine würde das so aber nicht merken.

Zitat von BBoy:
Hinzu kommt, dass natürlich nicht ständig die gewünschten daten im Datenstrom enthalten sind. Daher fällt möglichkeit eins (mit dem großen Puffer weg).
Nun ja, allparts sieht mir ein wenig nach einem globalen Puffer aus, in den Du hier z.B. einfach alle Daten schreibst, die gerade ankommen (und mit Start und Ende markiert wurden).
Jedenfalls ist ein großer Puffer an sich immer möglich (nur nicht unbedingt schön und/oder optimal). Die Idee hinter einem großen Puffer wäre folgende:
Du benutzt eine struktur, die Daten beliebiger Größe speichern kann. Denkbar wäre z.B. eine TStringList. Hier kannst Du einfach Strings hinzufügen oder entfernen. Kommt ein Datum an, dann fügst Du dieses einfach in die StringListe ein. Jetzt schaust Du, ob dieses Datum eine Anfang-Markierung enthält. Ist dies nicht der Fall, so gibt es zwei Möglichkeiten, entweder ist dieses Datum nichts oder es enthält einen Teil der Anfang-Markierung am Ende des strings. Hier reicht es, wenn Du eben die n-1 letzten Zeichen pufferst (wobei n = Length(%ANFANG)). Es kann sich max. %ANFAN am Ende des Strings befinden, bei mehr Zeichen der Anfang-Markierung wäre diese vollständig und gefunden wurden. Nun liest Du das folgende Datum ein. Erstelle hier den String aus dem gepufferten Datum und dem kompletten neuen String. Findest Du hier nun die Anfangmarkierung, so beginnt hier dein Datum. Ist dies nicht der Fall, so kannst Du den Inhalt des Puffers (die letzten n-1 Zeichen) komplett verwerfen und speicherst nun die n-1 letzten Zeichen dieses aktuellen Strings zwischen (auch hier kann sich ja jetzt ein Teil der Anfang-Markierung befinden).
Hast Du den Anfang erstmal gefunden, setzt Du Dein Flag und weißt, dass alle folgenden Daten gespeichert werden können (hast Du ja schon etwas für). Hier speicherst Du dann immer die letzten n-1 Zeichen in einem Puffer und suchst analog nach dem Ende.

Ok, das ist schon der Ansatz mit dem kleinen Puffer. Würdest Du aber die Daten alle in die Stringliste tun und immer den aktuellen String bzw. die Konkatenation aus aktuellem String und Vorgänger betrachten, so würdest Du sicherlich zum selben Ergebnis kommen (das wäre dann der globale Puffer). Natürlich rate auch ich Dir vom globalen riesen Puffer ab, da Du einen großen Teil der Daten sinnlos zwischenspeicherst.
Wenn aber z.B. zwei Nutzdatenpakete nicht all zu groß sind, dann kannst Du auch immer die letzten zwei empfangenen Daten betrachten. Hier müsste immer ein Anfang bzw. Ende aus deren Konkatenation hervor gehen. Dann musst Du nur beachten, dass Du keine Daten doppelt kopierst.

Gruß Der Unwissende
  Mit Zitat antworten Zitat