2012-10-06 26 views
2

在我目前的項目中,我們需要檢查文件是否仍在複製。如何檢查文件是否仍然使用Windows API在cpp中複製?

我們已經開發了一個庫,它會給我們一個特定文件夾的操作系統通知,如file_added,file_removed,file_modified,file_renamed以及相應的文件路徑。

這裏的問題是,可以說如果您添加1 GB文件,它會在複製文件時給出多個通知,如file_added,file_modified,file_modified。

現在我決定通過檢查文件是否複製來超越這些通知。基於此,我將忽略事件。

我已經在C++中編寫了下面的函數,它告訴我們文件是否被複制或者不需要文件路徑作爲輸入。 細節: - 基本上它使用Windows API「CreateFile」來獲取文件句柄。如果我們無法獲取句柄,則確定文件正在被複制。

問題: - 對於一些較大的文件,如2 GB與.rar & .exe格式,這不起作用。你可以請教我這是對的方法嗎?如果不理解其他方法。

bool isFileBeingCopied(const boost::filesystem::path &filePath) 
{ 
    //Log(INFO, "Checking if the given file is being copied or not for the file [%s]",filePath.string().c_str()); 
    HANDLE hFile = ::CreateFile(filePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 
    DWORD dwLastError = GetLastError(); 

    if(hFile == NULL && hFile == INVALID_HANDLE_VALUE) 
    { 
      Log(INFO, "Gained invalid handle on the file - hence determining it, as being copied file [%s]",filePath.string().c_str()); 
      return true; 
    } 
    else 
    { 
      if(dwLastError == ERROR_SUCCESS) 
      { 
       CloseHandle(hFile); 
       Log(INFO, "Able to gain the handle on the file - hence determining it, as copied file [%s]",filePath.string().c_str()); 
       return false; 
      } 
      else 
      { 
       Log(INFO, "Not able to gain the handle for the file - hence determining it, as being copied file [%s]",filePath.string().c_str()); 
       return true; 
      } 
    }    
} 

回答

0

如果該文件之前已經開放(現在仍然是)與dwShareMode = 0,督察,以獨佔訪問模式,你將不能夠直到它關閉再次打開它,不論是否文件正在被複制(=寫入),所以你的函數返回值true不能被依賴。

請注意,如果CreateFile()成功,請致電CloseHandle()並返回false。緊接着,文件可以被另一個進程打開以供寫入,並且由於這種競爭條件的可能性,返回的值false不能被依賴。如果你想阻止它,你不能關閉句柄,直到你不再有興趣獨佔訪問文件。

所以,這顯然不是正確確定文件是否被複制(=寫入)的正確方法。這似乎是一件毫無意義的事情。

在我看來,你試圖在這裏解決錯誤的問題。在你決定檢查一個文件是否被複制(=寫入)的情況下,真正的問題是什麼?如果你告訴我們,我們可能能夠幫助解決這個真正的問題。

+0

這不僅是獨佔訪問,可能會導致'的CreateFile()'失敗。只要該文件未打開進行讀取共享,由於此代碼正在請求它,那麼它將失敗。 –

+0

@RemyLebeau對,以前用'FILE_SHARE_WRITE'打開的文件將導致'CreateFile()'在'isFileBeingCopied()'中失敗。 –

+0

更準確地說,文件不是用'FILE_SHARE_READ'打開的。 –

1

除非您自己複製文件,否則無法從外部確定文件的複製狀態。您可能必須使用計時器來檢測文件修改事件何時停止發送給您。

+0

我想這樣我不能區分它是否是用戶手動編輯或文件複製 – Engineer

+0

看看是否創建一個[複製掛鉤處理程序](http://msdn.microsoft.com/en-us/library/windows/desktop/ cc144063.aspx)可以滿足您的需求。 –

1

使用boost filesystem libs,我們可以知道文件是否被複制。基本上boost :: filesystem :: fstream類爲I/O操作打開文件。當文件正在複製時,boost lib無法打開文件,is_open()方法將返回false。因此,在這種情況下,我們可以安全地假定該文件正在被複制。如果文件被破壞或損壞,我們最終會陷入這種情況。

在所有其他情況下,is_open()返回true,我們可以考慮文件複製完成(在這個用例中) 希望這段代碼有幫助。

boost::filesystem::fstream fileStream(filePath, std::ios_base::in | std::ios_base::binary); 

if(fileStream.is_open()) 
{ 
    //We could open the file, so file is good 
    //So, file is not getting copied. 
} 
else 
{ 
    //Wait, the file is currently getting copied. 
} 

編輯:添加更多的解釋

+0

請提供一些解釋,以使其更好理解。 – Shivaay

+0

添加說明 –

相關問題