Datentyp für Binärdaten?



  • Hallo,

    welchen Datentyp empfehlt ihr für Binärdaten (z.B. eine JPEG Datei) die ich über einen Netzwerkstream empfange?
    Ideen: char[], std::string, std::vector<char>, std::array, boost::buffer?

    mfg, René~



  • Kommt drauf an. Ist die Länge der zu empfangenden Daten bekannt? Sind es grosse Mengen, musst du sie zwischenspeichern oder kannst du sie teilweise bearbeiten? Für was brauchst du sie (als Bits (boost::dynamic_bitset oder std::vector<bool>) oder als die von dir genannten Möglichkeiten mit chars)?

    Das Beste wäre in einem so allgemeinen Fall, die Daten nicht im Zwischenspeicher zu halten, sondern gleich beim Empfangen zu bearbeiten. Aber für eine genauere Antwort benötigen wir mehr Informationen.



  • stebti schrieb:

    Kommt drauf an. Ist die Länge der zu empfangenden Daten bekannt?

    Nein, ich habe nur eine maximal erlaubte Größe.

    stebti schrieb:

    Sind es grosse Mengen, musst du sie zwischenspeichern oder kannst du sie teilweise bearbeiten?

    Im speziellen Fall programmiere ich gerade einen HTTP Bildupload, ergo wird es am Ende in eine Datei gespeichert. Da das HTTP Protokoll aber nicht gerade gut ist, kann ich den Stream nicht sofort in eine Datei schreiben sondern muss ständig gucken ob ich nicht die "Boundary" treffe und dann weiß ich erst wann die Datei zuende ist.

    mfg, René~



  • NewSoftzzz schrieb:

    ich [kann] den Stream nicht sofort in eine Datei schreiben sondern muss ständig gucken ob ich nicht die "Boundary" treffe und dann weiß ich erst wann die Datei zuende ist.

    Wie wäre es mit gucken→schreiben, ..., gucken→schreiben, gucken→Datei schliessen?



  • stebti schrieb:

    Wie wäre es mit gucken→schreiben, ..., gucken→schreiben, gucken→Datei schliessen?

    Ja natürlich, aber fürs gucken, die Frage bleibt: Welcher Datentyp? 😉

    mfg, René~



  • Als Datentyp empfiehlt sich alles was irgendwie mit Feld von char zu tun hat. Ich würde einen vector nehmen und ihn mit einer Anfangsgröße initialisieren. Bei Bedarf kann er im Nachhinein ohne Verlust der Daten vergrößert werden. Ob die Bilder dabei 10MB oder größer werden können spielt da keine wesentliche Rolle. Ich würde bei mehreren MB aber anfangen die Daten schon zwischendurch in eine Datei zu schreiben, wenn du sie dort haben willst.
    Das HTTP-Protokoll bietet dir übrigens die Größe im Header. Es ist also nicht notwendig irgendetwas auszutesten.



  • Nick Unbekannt schrieb:

    Das HTTP-Protokoll bietet dir übrigens die Größe im Header. Es ist also nicht notwendig irgendetwas auszutesten.

    Offensichtlich kennst du dich nicht genug mit dem HTTP Protokoll aus. Siehe:
    http://www.faqs.org/rfcs/rfc1867.html

    @Datentyp: ich tendiere zu einem string. Spricht was dagegen?

    mfg, René~



  • Ich finde die Stelle nicht wo steht, dass die Inhaltslänge nicht angegeben wird? Auch sehe ich an den Boundary-Marken keinen Hinweis, ob es die Letzte Marke ist oder nicht. Ich denke die Größe wird schon drin sein, allein damit alle Daten vom Stream gelesen werden. Oder wer garantiert zum Beispiel, dass die Marke nicht in den Daten vorkommt? Wenn du die Daten alle in einen string liest, kannst du anschließend mit find() die Marken suchen und so den Text zerpflücken. Dabei sollte aber darauf geachtet werden, in Binär-Daten können grundsätzlich Nullen drin sein.



  • char würde ich für Zeichen nehmen. Für Zahlen/Bytes am besten unsigned char (oder signed char ), weil man da einen standardisierten Wertebereich hat. Wieso std::string , wenn man keinen String braucht?

    Wenn du ein einfaches lineares Layout benötigst, könntest du es mit std::vector<unsigned char> versuchen.



  • Nick Unbekannt schrieb:

    Ich finde die Stelle nicht wo steht, dass die Inhaltslänge nicht angegeben wird?

    Die Inhaltslänge wird für den kompletten Content angegeben, der dann durch die boundaries erst mal in einzelne Elemente geteilt wird. Und diese Elemente haben wiederum einen Header aus Text und dann evtl. als eigenen Content Binärdaten, dessen Länge ist aber nicht angegeben.

    Nick Unbekannt schrieb:

    Auch sehe ich an den Boundary-Marken keinen Hinweis, ob es die Letzte Marke ist oder nicht.

    -- am Ende

    Nick Unbekannt schrieb:

    Oder wer garantiert zum Beispiel, dass die Marke nicht in den Daten vorkommt?

    Da muss sich der Client mittels Heuristiken drum kümmern. Kann aber schiefgehen.

    mfg, René~



  • Nexus schrieb:

    std::string , wenn man keinen String braucht?

    Die Daten selber sind ja in einem String eingebettet. Ich hatte damit gehofft über die String Methoden einfach die Byte-Folge für die Boundarys finden zu können. Leider orientiert sich std::string aber auch am Null-Byte, was somit nicht geht. Am unkompliziertesten ist aber nach wie vor ein vector.



  • Nick Unbekannt schrieb:

    Leider orientiert sich std::string aber auch am Null-Byte, was somit nicht geht.

    Was zum...?



  • Teufel!



  • NewSoftzzz schrieb:

    Nick Unbekannt schrieb:

    Leider orientiert sich std::string aber auch am Null-Byte, was somit nicht geht.

    Was zum...?

    Sorry, war falsch. Allerdings würde ich mich vorher vergewissern, ob diese Eigenschaft gewährt ist, wenn es portabel sein soll.



  • Grundsätzlich ist string aber keine gute Wahl. Es ist eben nicht garantiert, dass der Bereich, anders als bei vector, zusammenhängend im Speicher liegt.
    Ein vector<unsigned char> wäre wahrscheinlich das richtige. Du könntest ja auch jeweils die magic number auswerten, bei bekannten Formaten den Header einlesen und den vector gleich passend "resizen".


Log in to reply