1

MySql Connector C++ を使用して、JPEG 画像をファイルからデータベースに保存しています。私は準備されたステートメントを使用しています。準備済みステートメントの実行後、ファイルの最初の 64 バイトのみがデータベースにコピーされます。

私が例を調査したところ、反復は不要であり、例では、準備されたステートメントがファイル全体をロードすることを前提としています。これが私のコードです:

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();

テーブルのスキーマは次のとおりです。

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)

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)

準備されたステートメントでファイル全体を読み取るにはどうすればよいですか?
MySql Connector C++ で何かを初期化して、64 バイト以上を読み取らせる必要がありますか?

注: Windows XP および Vista で、MySql Connector C++ 1.0.5、Visual Studio 2008、および wxWidgets を使用しています。

テーブル作成ステートメント:

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

イメージ ファイルの 16 進ダンプ (Cygwin 経由):

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  
4

1 に答える 1

1

問題は、画像ファイルのコンストラクターにあります。

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

これには、バイナリ モード属性が必要です。

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

ファイルは JPEG 画像で、バイナリデータです。

また、バイト 65 の 16 進ダンプ1aは、Windows OS のファイル終了文字である を示しています:
0000040 1a 14 1115 1811 1821 1d1a 1f1d 1f1f 1713

コンストラクターを修正した後、MySql はデータ サイズを示します。

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)
于 2010-06-28T17:33:52.643 に答える