2013-01-31 32 views
2

我有一個函數來獲取文件的FileSize。我在WinCE上運行這個。這是我這似乎particularily慢更快的方法來獲取文件大小信息C++

int Directory::GetFileSize(const std::string &filepath) 
{ 
    int filesize = -1; 

#ifdef linux 
    struct stat fileStats; 
    if(stat(filepath.c_str(), &fileStats) != -1) 
     filesize = fileStats.st_size; 
#else 
    std::wstring widePath; 
    Unicode::AnsiToUnicode(widePath, filepath); 

    HANDLE hFile = CreateFile(widePath.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    if (hFile > 0) 
    { 
     filesize = ::GetFileSize(hFile, NULL); 
    } 

    CloseHandle(hFile); 
#endif 

    return filesize; 
} 
+2

您可能需要確認這是實際慢的代碼位。我沒有看到任何特別的原因,除非你的文件系統包含大量文件[因此,在所有文件中搜索需要一段時間才能打開]。 –

+0

@MatsPetersson你有一點,因爲我發佈這個,我意識到它可能是UnicodeToAnsi函數,因爲它涉及字符串操作。我重構了代碼以使用更少的代碼並將速度提高了30% – Chris

+0

如果您正在執行「許多」AnsiToUnicode調用,您可能需要構建一個緩存,檢查是否已經完成此文件並返回前一個文件。有些散列可能對此有所幫助。 –

回答

11

至少在Windows中,我想我會使用這樣的:

__int64 Directory::GetFileSize(std::wstring const &path) { 

    WIN32_FIND_DATAW data; 
    HANDLE h = FindFirstFileW(path.c_str(), &data); 
    if (h == INVALID_HANDLE_VALUE) 
     return -1; 

    FindClose(h); 

    return data.nFileSizeLow | (__int64)data.nFileSizeHigh << 32; 
} 

如果你正在使用的編譯器支持的話,你可能想使用long long而不是__int64。儘管如此,你可能做而不是想要使用int,因爲這隻對2GB的文件才能正常工作,而比這更大的文件現在很常見(儘管在WinCE設備上可能不常見)。

我想預計雖然這比其他大多數方法都快。它不需要打開文件本身,只需找到文件的目錄條目(或者在類似NTFS的情況下,它的主文件表條目)。

+0

從文件系統驅動程序的角度來看,目錄也是一個文件。打開一個目錄不能比打開一個普通文件快。 – xmllmx

+0

這是一種享受,謝謝!結合使用這種方式和減少對AnsiToUnicode的調用,我將之前編制索引的時間減半。每個變化都有同等貢獻 – Chris

+0

@傑裏,你是對的。您的解決方案確實節省了開放時間。 – xmllmx

-1

你可以滾你自己的,但我不明白爲什麼你的方法是緩慢的當前代碼:

int Get_Size(string path) 
{ 
// #include <fstream> 
FILE *pFile = NULL; 

// get the file stream 
fopen_s(&pFile, path.c_str(), "rb"); 

// set the file pointer to end of file 
fseek(pFile, 0, SEEK_END); 

// get the file size 
int Size = ftell(pFile); 

// return the file pointer to begin of file if you want to read it 
// rewind(pFile); 

// close stream and release buffer 
fclose(pFile); 

return Size; 
} 
+3

我非常懷疑添加幾層C庫代碼會讓它更快。 –

1

您的解決方案已經是相當快的查詢大小的文件。

在Windows下,至少對於NTFS和FAT,文件系統驅動程序會將文件大小保留在緩存中,因此查詢速度相當快。涉及的最耗時的工作是從用戶模式切換到內核模式,而不是文件系統驅動程序的處理。

如果您希望使速度更快,您必須在用戶模式下使用自己的緩存策略,例如,一個特殊的哈希表,以避免從用戶模式切換到內核模式。但我不建議你這樣做,因爲你的表現不會很好。 PS:你最好避免你的函數體中的語句Unicode::AnsiToUnicode(widePath, filepath);。這個功能相當耗時。

1

只是一個想法(我還沒有測試過),但我希望 GetFileAttributesEx在系統級別最快。它 避免了必須打開該文件,並在邏輯上,我認爲它 比FindFirstFile快,因爲它不必 維護任何信息繼續搜索。