2013-08-05 114 views
3

我正在使用庫函數_wsplitpath_s()來解析路徑,以便與Win32 API函數一起使用。_wsplitpath_s()替代長路徑使用

根據this MSDN document,長路徑(長於MAX_PATH個字符)必須與前綴\\?\一起執行。但是,當我將其轉換爲完整路徑字符串時,_wsplitpath_s()無法正確分析它。

示例代碼:

Full path to be splitted : \\?\K:\A Directory\Another Directory\File Name.After Period.extension 
Drive     : 
Directory    : \\?\K:\A Directory\Another Directory\ 
File name    : File Name.After Period 
Extension    : .extension 
Error value returned  : 0 
Did error occur?   : 0 
Value of 'EINVAL'  : 22 

工作原理與短的路徑:

Full path to be splitted : K:\A Directory\Another Directory\File Name.After Period.extension 
Drive     : K: 
Directory    : \A Directory\Another Directory\ 
File name    : File Name.After Period 
Extension    : .extension 

爲長路徑預期行爲:

std::wstring FullPath = L"\\\\?\\K:\\A Directory\\Another Directory\\File Name.After Period.extension"; 
std::wstring Drive, Directory, FileName, Extension; 
Drive.resize  (FullPath.size()); 
Directory.resize (FullPath.size()); 
FileName.resize  (FullPath.size()); 
Extension.resize (FullPath.size()); 
errno_t Error = _wsplitpath_s( FullPath.c_str(), 
           &Drive[0], 
           Drive.size(), 
           &Directory[0], 
           Directory.size(), 
           &FileName[0], 
           FileName.size(), 
           &Extension[0], 
           Extension.size()); 
std::wcout << L"Full path to be splitted : " << FullPath.c_str()  << std::endl; 
std::wcout << L"Drive     : " << Drive.c_str()  << std::endl; 
std::wcout << L"Directory    : " << Directory.c_str() << std::endl; 
std::wcout << L"File name    : " << FileName.c_str()  << std::endl; 
std::wcout << L"Extension    : " << Extension.c_str() << std::endl; 
std::wcout << L"Error value returned  : " << Error    << std::endl; 
std::wcout << L"Did error occur?   : " << (Error == EINVAL) << std::endl; 
std::wcout << L"Value of 'EINVAL'  : " << EINVAL    << std::endl; 

以上代碼的實際輸出

Full path to be splitted : \\?\K:\A Directory\Another Directory\File Name.After Period.extension 
Drive     : K: 
Directory    : \A Directory\Another Directory\ 
File name    : File Name.After Period 
Extension    : .extension 

是否有支持長路徑命名約定的_wsplitpath_s()替代方案?
按給定順序接受STL算法,Win32 API函數或C庫函數。

+0

究竟是什麼,你說是哪裏錯了?你提供的輸出對我來說看起來沒問題。 –

+0

@Drew McGomen:驅動器名稱返回空。實際上,驅動器名稱會隨着長路徑前綴一起駐留到目錄名稱。當然,我可以使我的代碼適應這種行爲,但我可以確保這個函數對於長路徑總是這樣工作。這是一種無證的行爲,沒有人可以保證函數的行爲永遠如此。 – hkBattousai

+0

等一下,我爲什麼提到?我是否發表評論並刪除它? –

回答

0

你可以寫一個包裝函數,簡單地跳過「長路」介紹人,例如:

errno_t _wsplitpath_long_s(
    const wchar_t * path, 
    wchar_t * drive, 
    size_t driveNumberOfElements, 
    wchar_t *dir, 
    size_t dirNumberOfElements, 
    wchar_t * fname, 
    size_t nameNumberOfElements, 
    wchar_t * ext, 
    size_t extNumberOfElements 
) 
{ 
    if (_wcsnicmp(path, L"\\\\?\\", 4) == 0) 
     path += 4; 
    return _wsplitpath_s(path, drive, driveNumberOfElements, 
     dir, dirNumberOfElements, fname, nameNumberOfElements, 
     ext, extNumberOfElements); 
}