Frage an c++, boost, boost-iostreams, std – Wie lese ich eine Datei aus std :: ifstream in ein unsigniertes char-Array?

4

So normal mache ich Sachen wie:

<code>    std::ifstream stream;
    int buff_length = 8192;
    boost::shared_array<char> buffer( new char[buff_length]);
    stream.open( path.string().c_str(), std::ios_base::binary);
    while (stream)
    {
            stream.read(buffer.get(), buff_length);
            //boost::asio::write(*socket, boost::asio::buffer(buffer.get(), stream.gcount()));
    }
    stream.close();
</code>

Ich frage mich, wie ich hineinlesen sollunsigned char Puffer (boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);)

Außerdem würde ich shared_ptr <std :: vector <uint8_t >> shared_array vorziehen Viktor Sehr
Einer der Fälle, in denenreinterpret_cast<> ist eigentlich der richtige Ansatz. Chad

Deine Antwort

1   die antwort
11

In einfachster Form:

<code>std::vector<unsigned char> vec(
      std::istreambuf_iterator<char>(std::cin)
    , std::istreambuf_iterator<char>()
    );
</code>

Ersetzenstd::cin mit deinem aktuellen Stream.

Das obige führt wahrscheinlich mehr als eine Speicherzuweisung durch (für Dateien, die größer als ein paar Bytes sind), weilstd::istreambuf_iterator<> ist ein Eingabe-Iterator, kein Zufallszugriffs- oder Weiterleitungs-Iterator, daher kann die Länge der Datei nicht durch Subtrahieren von Iteratoren wie gemessen werdenend - begin oder anrufenstd::distance(begin, end). Es kann auf eine Speicherzuordnung reduziert werden, wenn der Vektor zuerst leer erstellt wirdstd::vector<>::reserve() wird aufgerufen, um Speicher für die Dateilänge zu reservieren, und schließlich wird das Einfügen eines Bereichs aufgerufenvec.insert(vec.end(), beg, end) mitbeg undend Seinstd::istreambuf_iterator<> wie oben, um die gesamte Datei zu lesen.

Wenn die Dateigröße mehr als ein paar Kilobyte beträgt, ist es möglicherweise am effizientesten, sie dem Prozessspeicher zuzuordnen, um zu vermeiden, dass Speicher vom Kernel in den Benutzerbereich kopiert wird.

Der Grundstd::istreambuf_iterator<char> wird verwendet, weil die Implementierung verwendetstd::char_traits<> das hat normalerweise spezialisierungen nur fürchar undwchar_t. Unabhängig davon erfordern die C- und C ++ - Standards allechar Typen, die das gleiche binäre Layout ohne Füllbits haben, also Konvertierungen zwischenchar, unsigned char undsigned char (die alle verschiedene Typen sind, im Gegensatz zusigned int undint Bitmuster erhalten und sind somit sicher.

[basic.fundamental / 1]

Einfachchar, signed char, undunsigned char Es gibt drei verschiedene Typen, die gemeinsam genannt werdenschmale Zeichentypen. EINchar, einsigned char, und einunsigned char belegen die gleiche Menge an Speicher und haben die gleichen Ausrichtungsanforderungen; das heißt, sie haben die gleiche Objektdarstellung ... Bei schmalen Zeichentypen sind alle Bits der Objektdarstellung an der Wertdarstellung beteiligt ... Bei vorzeichenlosen schmalen Zeichentypen steht jedes mögliche Bitmuster der Wertdarstellung für eine bestimmte Zahl. Diese Anforderungen gelten nicht für andere Typen. In einer bestimmten Implementierung eine Ebenechar object kann die gleichen Werte annehmen wie asigned char oder einunsigned char; welches ist implementierungsdefiniert. Für jeden Werti vom Typunsigned char Im Bereich von 0 bis einschließlich 255 ist ein Wert vorhandenj vom Typchar so dass das Ergebnis einer ganzzahligen Umrechnung voni zuchar istjund das Ergebnis einer ganzzahligen Umrechnung vonj zuunsigned char isti.

Die Standards verlangen das nichtchar c = -1; unsigned char u = c; Ergebnisse inc undu dasselbe Bitmuster haben. Theoretisch könnten vorzeichenbehaftete Zeichen das 1er-Komplement oder die Vorzeichengröße verwenden. M.M
@ M.M hat das Zitat für Sie hinzugefügt. Maxim Egorushkin
Nicht negativ Werte von vorzeichenbehafteten Zeichen müssen dieselbe Darstellung haben wie die entsprechenden vorzeichenlosen Zeichen. Aber in der Ergänzung zum Beispiel,char c = -1; hat Bitmuster 11111110 währendunsigned char u = c; hat Bitmuster 11111111. Dies ist größtenteils akademisch, da mir keine C ++ - Implementierung bekannt ist, bei der das 2er-Komplement nicht verwendet wurde M.M
+1 für den letzten Absatz sehe

Verwandte Fragen