使用 sqlite3_column_text 讀取資料庫中儲存的十六進位二進位資料時,遇到 0x00 空字元導致 C 風格字串提早結束,無法正確取得完整資料長度。
使用 sqlite3_column_bytes 取得欄位實際位元組長度,而非依賴字串結束字元。
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int iCol);
// 假設已準備好 statement 並 step 到目標列
const unsigned char* blobData = sqlite3_column_blob(stmt, colIndex);
int dataLen = sqlite3_column_bytes(stmt, colIndex);
if (blobData != nullptr && dataLen > 0) {
// 正確處理包含 0x00 的二進位資料
std::vector buffer(blobData, blobData + dataLen);
// 後續處理 buffer...
}
| 函式 | 用途 | 適用場景 |
|---|---|---|
sqlite3_column_text | 取得 UTF-8 文字指標 | 純文字資料,不含 0x00 |
sqlite3_column_blob | 取得二進位資料指標 | BLOB、含 0x00 的資料 |
sqlite3_column_bytes | 取得資料位元組長度 | 配合 blob 使用,正確處理長度 |
sqlite3_column_bytes16 | 取得 UTF-16 位元組長度 | UTF-16 編碼文字 |
// 錯誤:strlen 遇到 0x00 會提早結束
int len = strlen((char*)sqlite3_column_text(stmt, 0));
// 錯誤:sqlite3_column_text 回傳的指標不可直接當二進位用
const char* ptr = (const char*)sqlite3_column_text(stmt, 0);
// 正確:使用 blob + bytes
const void* data = sqlite3_column_blob(stmt, 0);
int len = sqlite3_column_bytes(stmt, 0);
// 現在擁有完整資料指標與正確長度
若資料庫經加密或無法修改結構(無法新增長度欄位),sqlite3_column_bytes 更是唯一可行方案。此時資料屬於「不透明二進位區塊」,應用層只需正確讀取長度與內容,交由解密模組處理即可。
SQLite 讀取二進位資料的核心原則:永遠搭配 sqlite3_column_blob 與 sqlite3_column_bytes 使用。這組 API 能正確處理包含任意位元組值(含 0x00)的資料,是處理加密資料、序列化物件、圖片二進位等場景的標準作法。