關於ReadDirectoryChangesW API的使用方式 |
答題得分者是:小傑克
|
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
這幾天一直在研究這方面的東西,但實作上真的卡很多東西
網路上的範例在我看起來,說實在的很多東西看不懂,在此提出我的疑點 希望前輩們能多多指教 根據 ReadDirectoryChangesW 定義如下 BOOL ReadDirectoryChangesW( HANDLE hDirectory, \\監控路徑 LPVOID lpBuffer, \\緩衝區初始設置,雖然知道,但要怎麼設,是否有什麼技巧? DWORD nBufferLength, \\緩衝區長度設置 BOOL bWatchSubtree, \\是否監控子目錄 DWORD dwNotifyFilter, \\設定要過濾的條件 LPDWORD lpBytesReturned, \\請前輩指教 LPOVERLAPPED lpOverlapped, \\請前輩指教 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine \\請前輩指教 ); 而ReadDiectoryChangesW的 hDirectory 不能直接指定目錄嗎? 為什麼網路上會有範例說利用CreateFile來取得 hDirectory的返回值? 以上就是我對這個函數的質疑部份~ 希望有空的前輩們幫忙回答一下~ 基本功不夠,我會再努力精進的,先謝謝各位前輩了~
------
尋找對的人,對的方法,對的態度跟對的環境 |
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
看的出來想完全只靠MSDN 寫出這個sample 不容易, 可能要試很久 , 還好總是有前輩已經花時間去做
實際上程式寫法參考這篇 http://www.delphipages.com/threads/thread.cfm?ID=23571&G=23547 定義方面可以參考 http://msdn.microsoft.com/en-us/library/aa365465(VS.85).aspx 至於路徑說明如下 hDirectory [in] A handle to the directory to be monitored. This directory must be opened with the FILE_LIST_DIRECTORY access right. 如何opened with the FILE_LIST_DIRECTORY access right 則要看另外兩篇 http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx 參數 The requested access to the file or device, which can be summarized as read, write, both or neither (zero). The most commonly used values are GENERIC_READ, GENERIC_WRITE, or both (GENERIC_READ | GENERIC_WRITE). For more information, see File Security and Access Rights. 而這個參數的內容要參考 http://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx 要用windows api 本來就要依照api的定義, 既然規定directory handle 要用 File access right 中參數FILE_LIST_DIRECTORY 取得, 當然就要這樣繞一下 希望這些資料有幫到你
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-05-22 13:26:39, 註解 無‧
|
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
|
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
這兩天研究該程式的結果,發現有幾個問題點還蠻怪的
可能我對這位作者的寫法有些地方產生很多疑問吧 我想說列舉一下,希望有經驗的前輩們能指導一下 一直麻煩前輩們幫忙解答,真是謝謝您們了,尤其是小傑克前輩 問題點如下: 1、CreateFile [code delphi] FDirectoryHandle := CreateFile(PChar(edRule.Text), FILE_LIST_DIRECTORY, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED,0); //---------------------------------------------------------------------------- FDirectoryHandle := CreateFile(PChar(edRule.Text), FILE_LIST_DIRECTORY, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED,nil); [/code] 當我設最後一個參數nil時,則在comple的時候,就過不了了,會發生型態錯誤 [DCC Error] frmWatch.pas(135): E2010 Incompatible types: 'Cardinal' and 'Pointer' 而我去參考help的時候,它說這個欄位的值可以為null 那這邊的0代表的意思是等於null的意思嗎?
------
尋找對的人,對的方法,對的態度跟對的環境 |
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
2、程式碼如下
[code delphi] FCompletionPort := CreateIoCompletionPort(FDirectoryHandle, 0, Longint(pointer(self)), 0); ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer)); //為什麼要在記憶體空間裡面未填入值的空間都寫入0呢?用意是什麼呢? FBytesWritten := 0; [/code] 2.1 其中Longint(pointer(self))這段程式碼的轉型不太了解,我知道self是代表目前的Form 我有透過ShowMessage(IntToStr(Longint(pointer(self))))來看到底轉出什麼東西 但這樣的結果反而是一串整數,是代表一個位置嗎?
------
尋找對的人,對的方法,對的態度跟對的環境 |
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
3. ZeroMemory的問題
[code delphi] procedure TWaitThread.Execute; var .... begin while not Terminated do begin GetQueuedCompletionStatus( FForm.FCompletionPort, numBytes, CompletionKey, FForm.FPOverlapped, INFINITE); if CompletionKey <> 0 then begin Synchronize(HandleEvent); with FForm do begin FBytesWritten := 0; ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer)); //為什麼在這邊又要在做一次ZeroMemory呢@@? ReadDirectoryChangesW(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer), true, FNotifyFilter, @FBytesWritten, @FOverlapped, nil); end; end end; end; [/code]
------
尋找對的人,對的方法,對的態度跟對的環境 |
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
你一次問了好幾個...這我也沒實際寫過, 沒辦法我只好去 DelphiPage 再看了一下整個sample , 有可能講的不對,大家交流一下
1. null是傳 0 沒錯, 因為他參數型態是 handle = type LongWord , 有些function 回傳 HWND會用0 或 -1 表示null 或錯誤 , 正常時會是一個常整數, 而 NIL 是 null Pointer , Pointer型別用的 2. CreateIoCompletionPort 第三個參數, 根據http://msdn.microsoft.com/en-us/library/aa363862(VS.85).aspx 的說明, 是使用者自定的一個變數,這個變數CompletionKey 是取回資料的時候識別用的, 詳細內容還有和GetQueuedCompletionStatus , PostQueuedCompletionStatus的關聯 在msdn的remark 段落有說明 3. 至於ZeroMemory .....因為每次用ReadDirectoryChangesW 之前都要先初始化 FNotificationBuffer , 他 thread execute 裡面是用 while not Terminated do 沒按下中斷紐之前會一直loop的
------
額有朝天骨,眼中有靈光 |
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
不好意思,小傑克前輩
這麼晚才回您,因為這幾天ktop好像不怎麼穩定 有時候會沒辦法上 可能是相關人員在做維修或者發生什麼事也不一定 以致於這麼晚才回您 謝謝您的答覆,這幾個禮拜以來一直麻煩您了 改天有機會見面的話,再請你吃個飯跟你說聲謝謝 關於您說的這幾個解答,我會在try的,因為我寫的程式跑出來的結果並不是我要的 thread並沒有辦法像loop一樣重覆執行,我想應該是我那個地方寫錯了 目前還在查找bug當中,還是那句話,謝謝您的用心,感謝~^^
------
尋找對的人,對的方法,對的態度跟對的環境 |
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
大家交流心得,別這麼客氣
試試這個 http://delphi.ktop.com.tw/board.php?cid=32&fid=911&tid=98471 我拿那個sample 改的, 只多加兩三行處理event 比對 , 你可以直接監控整個硬碟, 檔案跑到哪邊去都知道 我的比對法,是用最後一個remove event 和下一個add event 比對, 當一次移動超過一個以上的檔案時, 不一定會全部抓到, 因為file system 有同步的問題, 不是先進先出的, 所以還可以再改進 , 以一次移動為單位, 將全部 remove 檔都寫到 list 裡面, Add 的時候比對才不會少 , 如果要很完整的功能 ,要考慮的東西還蠻多的
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-05-27 04:42:39, 註解 增加說明‧
|
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
|
terrygobb
一般會員 發表:5 回覆:22 積分:5 註冊:2009-04-27 發送簡訊給我 |
Dear 小傑克前輩:
剛在研讀您的sample的時候,發現的原始程式碼 希望對大家有幫助,我去用功了,呵~再跟您說聲謝謝啦 謝謝您的提醒,我太粗心了 每天都有新的進度,雖然一直卡住,自己也很難過,但過程咩~ 我會加油滴~ 祝大家端午節快樂^^~ 網址如下: http://www.4shared.com/file/108058889/42333ebf/dirmon.html
------
尋找對的人,對的方法,對的態度跟對的環境
編輯記錄
terrygobb 重新編輯於 2009-05-27 16:32:00, 註解 無‧
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |