Frage

Es gibt eine Frage, die ich gefragt habe, etwa für Alter und ich habe gehofft, dass mir jemand eine Antwort geben könnte meinen Geist zur Ruhe.

Nehmen wir an, dass ich einen Eingangsstrom haben (wie eine Datei / Buchse / Rohr) und wollen die eingehenden Daten analysieren. Nehmen wir an, dass jeder Block der eingehenden Daten durch eine neue Zeile aufgeteilt ist, wie die meisten gemeinsame Internet-Protokolle. Diese Anwendung könnte genauso gut sein Parsing HTML, XML oder andere intelligente Datenstruktur. Der Punkt ist, dass die Daten in logische Blöcke durch ein Trennzeichen unterteilt sind eher als eine feste Länge. Wie kann ich die Datenpuffer zu warten, bis der Begrenzer erscheinen?

Die Antwort scheint einfach genug. Nur einen ausreichend großen Byte / char-Array hat die ganze Sache passen

Was aber, wenn das Trennzeichen kommt, nachdem der Puffer voll ist? Dies ist eigentlich eine Frage, wie ein dynamischen Datenblock in einem Block festen Größe zu passen. Ich kann nur wirklich denken Sie an ein paar Alternativen:

  1. Erhöhen Sie die Puffergröße, wenn nötig. Dies kann schwere Speicher Neuzuweisung erfordern, und führt Erschöpfung aus speziell gestalteten Strom (oder vielleicht sogar Denial-of-Service im Fall von Sockets Ressource, wo wir sie gegen Erschöpfung Angriffe und Drop-Verbindungen schützen wollen, die versuchen, Ressourcen zu erschöpfen ... und ein Angreifer beginnt mit dem Senden gefälschte, übergroße Pakete den Schutz auszulösen).

  2. Starten Sie alte Daten überschrieben werden durch einen Ringpuffer verwendet wird. Vielleicht nicht die ideale Methode, da der logische Block wäre unvollständig werden.

  3. neue Daten-Dump, wenn der Puffer voll ist. Allerdings ist diese Art der Begrenzer wird nie gefunden werden, so dass diese Wahl ist offensichtlich nicht eine gute Option.

  4. Nur die feste Größe Puffer machen verdammt groß und übernimmt alle eingehenden logische Datenblocks innerhalb seiner Grenzen ... und wenn es jemals füllt, interpretiert nur den vollen Puffer als logischen Block ...

In jedem Fall ich, wir fühlen müssen davon ausgehen, dass die logischen Blöcke werden nie eine bestimmte Größe überschreiten ...

Alle Gedanken zu diesem Thema? Offensichtlich muss es eine Möglichkeit sein, da die höheren Sprachen eine Art Puffermechanismen mit ihren readLine() Strom Methoden bieten.

Gibt es einen „besten Weg“, dies zu lösen, oder gibt es immer einen Kompromiss? Ich schätze alle Gedanken und Ideen zu diesem Thema wirklich da diese Frage wurde mir spukt jedes Mal habe ich brauchte einen Parser von einer Art zu schreiben.

War es hilfreich?

Lösung

Es gibt normalerweise zwei Techniken für diesen

1) Was ich denke, Readline- Verwendung - wenn der Puffer die Daten ohne Trennzeichen am Ende füllt zurückkehren

2) Wenn der Puffer voll ist, remeber es gefüllt, lesen Sie, bis Sie das Trennzeichen erhalten und einen Fehler melden (oder den Datensatz in der Puffergröße gestutzt)

Andere Tipps

Optionen (2) und (3) ist, wie Sie Daten in beiden Fällen verlieren. Option (4) eines großen Puffer fester Größe würde das Problem nicht lösen, da es einfach nicht möglich ist, zu wissen, welche Größe groß genug ist? Ist es den alle physischen Speicher + Swap-Speicher + der freie Speicherplatz in allen Platten überall im bekannten Universum?

sieht aus wie die beste Lösung, um die Puffergröße ändern. Sagen Sie realloc auf die doppelt so groß und weiter schreiben. Es gibt immer eine Chance auf einen speziell wie ein DoS konstruiert Stream, um das System zu bringen versucht. Mein erster Gedanke war so eine beliebig große Größe wie die max_size für den Puffer eingestellt. Wenn wir jedoch das tun könnten, könnten wir nur festgelegt, dass, wenn die Größe des großen Puffer. So sieht den Puffer Ändern der Größe wie die beste Option für mich.

  1. Wenn das Protokoll oder Sie definieren nicht eine obere Grenze für die Länge eines jeden Blocks dann sehe ich nicht, wie Sie Speicher Erschöpfung Grenzfälle verhindern kann.

  2. Unter der Annahme, dass es eine obere Schranke ist eine feste Größe Block mit scheint ein guter Ansatz für eine vernünftige Größe Grenzen gesetzt.

  3. Wenn die Grenzwerte sind so hoch, dass ein einziger fester Puffer ineffizient sein wird, dann würde ich vorschlagen, eine Datenstruktur, die intern als eine verknüpfte Liste mit fester Größe Puffer implementiert wird.

Warum müssen Sie starten warten Verarbeitung?

Generell Alternative 4 ist Klang. Es ist jedoch nicht, erfordert eine „Annahme“, sondern eine Definition. Sie erklären lediglich, dass Blöcke kleiner als 8K und mit ihr geschehen. Es ist nicht schwer zu tun.

Außerdem gibt es alternative 5: Teil-Puffer Verarbeitung starten. Dies funktioniert, wenn Sie ein wirklich pathologisches Protokoll entworfen haben, die am Ende des Blockes kritische Daten senden.

HTML, XML, JSON / YAML, etc., können alle schrittweise analysiert werden. Sie dies nicht tun erforderlich ein delimeter nützliche Verarbeitung zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top