представление больших двоичных объектов в C++

Существуют ли контейнеры STL, которые хорошо подходят для использования в качестве больших двоичных объектов для программного обеспечения баз данных? Я бы подумал vector<char>, но есть ли что-то лучше? Может std::string? Или какой-то не-STL-контейнер?


person Baruch    schedule 20.05.2012    source источник
comment
Ну, это текстовая строка? Если нет (поскольку BLOB — это просто куча двоичного мусора), то std::string — плохая идея. В том же смысле вектор chars (которые являются текстовыми символами) плохая идея по сравнению с вектором unsigned chars.   -  person Christian Rau    schedule 20.05.2012
comment
@ChristianRau: char не является текстовым символом. string неплохая идея.   -  person Kerrek SB    schedule 20.05.2012
comment
@KerrekSB Ну, концептуально так и есть. И концептуально строка — плохая идея для нетекста. Концептуально, конечно.   -  person Christian Rau    schedule 20.05.2012
comment
@ChristianRau: Нет. Концептуально char — это наименьшая адресуемая единица данных и основная единица ввода-вывода. Таким образом, это идеальный тип для представления произвольных данных. Единственное, что не так с char, это его собственное имя.   -  person Kerrek SB    schedule 20.05.2012
comment
@KerrekSB Тогда нет ли разницы между char и unsigned char, когда они не используются для чисел?   -  person Baruch    schedule 20.05.2012
comment
@KerrekSB Ну, я бы предпочел тип с определенной (для нескольких платформ) подписью, учитывая, что двоичными данными часто лучше всего манипулировать как последовательностью целых чисел. Хотя вы правы в том, что если вы не манипулируете им (как это может быть в случае с BLOB), может быть достаточно неопределенной подписи. Но у меня просто есть возражение против неуказанной подписи, и для ма char это символ, может быть просто что-то субъективное без причины.   -  person Christian Rau    schedule 20.05.2012
comment
Вот как обрабатываются BLOBS в OTL — otl.sourceforge.net/otl3_lob_stream.htm   -  person bobah    schedule 20.05.2012
comment
@baruch: signed char и unsigned char являются арифметическими целочисленными типами, такими как int и unsigned int. С другой стороны, char явно предназначен для того, чтобы быть типом ввода-вывода, который представляет некую непрозрачную, специфичную для системы фундаментальную единицу данных на вашей платформе. Я бы использовал их в этом духе.   -  person Kerrek SB    schedule 20.05.2012
comment
@KerrekSB Но хорошо, даже если char лучше всего использовать для двоичных данных (с чем вы, кажется, правы), std::string определенно нет, поскольку концептуально это текстовая строка. Вы не хотите использовать какие-либо сравнения и преобразования на основе локали для двоичных данных, не говоря уже о завершении NUL.   -  person Christian Rau    schedule 20.05.2012
comment
@boba Что такое? символы, беззнаковые символы, векторы, строки?   -  person Baruch    schedule 20.05.2012
comment
@baruch, этот конкретный пример был с потоком, это ссылка на полный список примеров otl.sourceforge.net /otl3_examples.htm, я предложил посмотреть его, потому что OTL — это один заголовок, и если вы найдете пример, который соответствует вашему варианту использования, вы можете проверить исходный код ниже и сделать то же самое.   -  person bobah    schedule 20.05.2012


Ответы (3)


Базы данных типа BLOB позволяют хранить двоичные данные, поэтому вам нужен упорядоченный набор байтов. Самым простым выбором будет vector<>, и вы можете выбрать unsigned char для представления байта на большинстве платформ.

person Attila    schedule 20.05.2012

Мы использовали streams в одном из наших проектов для представления значений BLOB/CLOB, хранящихся в базе данных. Я думаю, что в большинстве случаев это лучший подход, поскольку BLOB/CLOB могут быть очень большими, чтобы поместиться в памяти по определению.

Напишите свою собственную реализацию stream и используйте ее так же, как любую другую stream.

person Hakan Serce    schedule 20.05.2012

В настоящее время я использую std::string для хранения больших двоичных объектов, так как использую библиотеку Google Protocol Buffers для сериализация объектов, и это то, что они используют (например, MessageLite::SerializeToString). Это хорошо работает для моих целей, так как вставить результирующую строку в виде большого двоичного объекта в базу данных SQLite очень просто:

sqlite3_bind_blob(_insert_statement, 3, data.c_str(), data.size(), SQLITE_STATIC);

(data — это std::string, связанный в качестве третьего аргумента с _insert_statement.)

person Ian Mackenzie    schedule 20.05.2012
comment
Как заполнить строку? - person Peter Wood; 21.05.2012
comment
Взгляните на пример протокольных буферов; вместо person.SerializeToOstream(&output) я использую person.SerializeAsString(), а затем использую результат как большой двоичный объект SQLite. Также есть SerializeToString(std::string*), если вы действительно хотите избежать копирования. - person Ian Mackenzie; 15.06.2012