首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQLite3 中文路徑開啟失敗?UTF-8 編碼轉換一行搞定

     編輯:關於SqlServer

SQLite3 預設 API 僅接受 UTF-8 編碼的檔案路徑。當資料庫檔案置於包含中文的目錄 (如 C:\我的資料\db.sqlite) 時,直接傳入 ANSI/MBCS 路徑會導致 sqlite3_open 失敗 (返回 SQLITE_CANTOPEN)。解決關鍵:**將路徑轉為 UTF-8 再呼叫 API**。

問題重現

// 錯誤示範:中文路徑直接傳入
sqlite3_open("C:\\我的資料\\db.sqlite", &db); // 失敗

完整解決方案 (ATL/MFC 環境)

char szFileNameUtf8[MAX_PATH * 4];  // UTF-8 可能較長,預留 4 倍空間
_bstr_t bstrFileName = strPath;     // strPath 為 CString/TCHAR* 原始路徑

if (HasChineseChar(strPath))        // 簡易判斷是否含中文 (或直接全部轉換)
{
    // ATL 提供 Unicode → UTF-8 轉換
    AtlUnicodeToUTF8(bstrFileName, bstrFileName.length(), szFileNameUtf8, sizeof(szFileNameUtf8));
    result = sqlite3_open(szFileNameUtf8, &m_sqlite3DB);
}
else
{
    // 純 ASCII 路徑可直接使用
    result = sqlite3_open(strPath, &m_sqlite3DB);
}

if (result == SQLITE_OK)
{
    char *errmsg = NULL;
    int nError = sqlite3_exec(m_sqlite3DB,
        "CREATE TABLE Table_a( ID INTEGER PRIMARY KEY AUTOINCREMENT, name NVARCHAR(32) )",
        NULL, NULL, &errmsg);
    if (nError != SQLITE_OK)
    {
        ATLTRACE("建立資料表失敗,錯誤碼:%d,原因:%s\n", nError, errmsg);
        sqlite3_free(errmsg);
    }
}

輔助函數:偵測中文字元

bool HasChineseChar(const CString& str)
{
    for (int i = 0; i < str.GetLength(); ++i)
    {
        // 簡易判斷:雙位元組字元 (中文 Big5/GBK 皆大於 0x80)
        if (static_cast(str[i]) > 0x80) return true;
    }
    return false;
}

跨平台/標準 C++ 替代方案

  • C++17 std::filesystem::path:原生支援 Unicode,配合 sqlite3_open16 (接受 UTF-16) 最簡潔
  • Windows API WideCharToMultiByte(CP_UTF8, ...):無 ATL 依賴的通用做法
  • ICU / Boost.Locale:專案已引入國際化庫者首選

關鍵提醒

  1. SQLite 3.38+ 新增 sqlite3_open16 直接接受 UTF-16 (Windows wchar_t*),可完全避開轉碼麻煩
  2. 資料庫內容 (文字欄位) 亦建議統一存 UTF-8,避免編碼地獄
  3. 檔案路徑長度可能超過 MAX_PATH (260),建議使用延長路徑前綴 \\\\?\\ 或動態配置緩衝區

一行 AtlUnicodeToUTF8 (或 WideCharToMultiByte),徹底解決 SQLite3 中文路徑難題,讓資料庫部署不再受限於目錄命名習慣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved