Pregunta

Estoy utilizando el MySQL Connector C ++ para almacenar una imagen JPEG de un archivo en la base de datos. Estoy usando la declaración preparada. Después de la ejecución de la declaración preparada, sólo los primeros 64 bytes del archivo se copian en la base de datos.

Mi investigación de los ejemplos muestran que ninguna iteración es necesario y los ejemplos se supone que las cargas declaración preparada el archivo completo. Aquí está mi código:

std::string         statement_text("INSERT INTO ");
statement_text += "picture_image_data";
statement_text += " (";
statement_text += "ID_Picture";
statement_text += ", ";
statement_text += "Image_Data";
statement_text += ") VALUES (?, ?)";    
wxLogDebug("Creating prepared statement using:\n%s\n", statement_text.c_str());
std::string filename("my_image.jpg");
Ptr_Db_Connection                           db_conn(db_mgr.get_db_connection());
boost::shared_ptr<sql::PreparedStatement>   prepared_statement(db_conn->prepareStatement(statement_text));
prepared_statement->setInt(1, picture_id);
std::ifstream   blob_file(filename.c_str());
prepared_statement->setBlob(2, &blob_file);
prepared_statement->execute();
blob_file.close();

Este es el esquema de la tabla:

mysql> describe picture_image_data;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| ID_Picture | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| Image_Data | mediumblob       | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

Desde la consola de MySQL:

mysql> select ID_Picture, LENGTH(image_data)
    -> FROM picture_image_data
    -> where ID_Picture = 1;
+------------+--------------------+
| ID_Picture | LENGTH(image_data) |
+------------+--------------------+
|          1 |                 65 |
+------------+--------------------+
1 row in set (0.02 sec)

¿Cómo hago la declaración preparada leer todo el archivo?
¿Es necesario para inicializar nada en MySQL Connector C ++ para hacer esta lectura más de 64 bytes?

Nota:. Estoy utilizando MySQL Connector C ++ 1.0.5, Visual Studio 2008 y wxWidgets en Windows XP y Vista

sentencia de creación de tabla:

CREATE TABLE Picture_Image_Data
(
    ID_Picture INTEGER UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    Image_Data MEDIUMBLOB
);

volcado hexadecimal (a través de Cygwin) del archivo de imagen:

0000000 d8ff e0ff 1000 464a 4649 0100 0101 1c00
0000010 1c00 0000 dbff 4300 0500 0403 0404 0503
0000020 0404 0504 0505 0706 080c 0707 0707 0b0f
0000030 090b 110c 120f 1112 110f 1311 1c16 1317
0000040 1a14 1115 1811 1821 1d1a 1f1d 1f1f 1713
0000050 2422 1e22 1c24 1f1e ff1e 00db 0143 0505
0000060 0705 0706 080e 0e08 141e 1411 1e1e 1e1e
0000070 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e  
¿Fue útil?

Solución

La cuestión radica en el constructor del archivo de imagen:

std::ifstream   blob_file(filename.c_str());

Esto debe tener el atributo modo binario:

std::ifstream   blob_file(filename.c_str(), std::ios_base::binary);

El archivo, una imagen JPEG, es binario de datos.

Además, el volcado hexadecimal del byte 65 muestra 1a, que es el fin del sistema operativo Windows de caracteres de archivo:
0000040 1a 14 1115 1811 1821 1d1a 1f1d 1f1f 1713

Después de fijar el constructor, los espectáculos MySql el tamaño de datos:

mysql> SELECT ID_Picture, LENGTH(Image_Data)
    -> FROM picture_image_data
    -> WHERE ID_Picture = 1;
+------------+--------------------+
| ID_Picture | LENGTH(Image_Data) |
+------------+--------------------+
|          1 |              18453 |
+------------+--------------------+
1 row in set (0.00 sec)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top