[問題] 偵測大型檔案copy完成

看板java作者 (小黑炭)時間7年前 (2016/08/05 00:58), 7年前編輯推噓10(10040)
留言50則, 9人參與, 最新討論串1/2 (看更多)
Hi all, 想請問大家都怎麼偵測大檔案copy完成了呢? 使用情境是: user丟大型檔案到指定資料夾 > 抓到這個事件 > 做其他事情 問題點: 現在卡在"抓到這個事件"有點不太好處理, 想請各位版友分享類似經驗 已嘗試方法: 1) 透過 nio 的 WatchService 這個方法基本上就是google的第一種解法, 透過 nio 的 WatchService, 註冊 ENTRY_MODIFY/ENTRY_CREATE 可偵測到檔案有變動or新增 但無法無法知道何時copy完成 2) 在 nio 的 WatchService 判斷 天真如我, 在每次 ENTRY_MODIFY 事件發生時, 將 Path 轉為 File, 判斷檔案是否可用 File f = path.toFile(); if(f.canWrite()){ ... } 會用 canWrite() 判斷是因為有爬到說在copy時檔案不能編輯 這個方法我一直覺得可能是我哪邊寫錯了, 因為我覺得應該要可以 Orz 3) 定時爬一次資料夾 這是土炮, 也是唯一成功的一種... for(;;){ ...; Thread.sleep(5000); } 不想用這種方法的原因是, 類似的回答在 stackoverflow 被推到 -1x 也有人點出效能的問題 以上是我嘗試過的幾種方式, 不知道有沒有其他我沒想過的做法可以提供參考 跪謝 -- 不菸不酒,沒有朋友 有菸有酒,癌症好友 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.224.100.95 ※ 文章網址: https://www.ptt.cc/bbs/java/M.1470329900.A.A79.html

08/05 01:56, , 1F
public void observe(){ copyingFile(); notifyDone()
08/05 01:56, 1F

08/05 01:56, , 2F
;}
08/05 01:56, 2F
謝謝 可以詳述一下這是怎麼做的嗎@@? 只有兩個function name 我參悟不出來 Orz ※ 編輯: love112302 (61.224.100.95), 08/05/2016 08:45:11

08/05 09:11, , 3F
簡單來說你寫copy的那個method最後一行加個通知完成
08/05 09:11, 3F

08/05 09:11, , 4F
的method
08/05 09:11, 4F

08/05 09:13, , 5F
不過不太確定你的寫法適合嗎,我是都用古老的copy寫法
08/05 09:13, 5F

08/05 09:13, , 6F
08/05 09:13, 6F
Hi, 謝謝您的意見, 但是 copy檔案這個部分不是我做的 是使用者自行丟檔案到特定資料夾, 所以好像沒辦法這樣做 @@?

08/05 11:50, , 7F
那是偵測檔案異動 不適合你的需求
08/05 11:50, 7F

08/05 11:51, , 8F
如果丟檔的行為 也是靠你的程式處理 那就很簡單單純
08/05 11:51, 8F

08/05 11:56, , 9F
而且至少還能掌握大檔丟完後的完整性
08/05 11:56, 9F

08/05 12:03, , 10F
寫批次也能做到 複製完 %errorlevel%跟起始時間出log
08/05 12:03, 10F
謝謝 想請問批次是指 batch? 不好意思這塊不太熟, 我原本也是想用 batch 來監看資料夾, 如果copy完成, 執行特定的 jar 檔案, 但因為command line 指令不熟放棄 T__T ※ 編輯: love112302 (114.46.155.75), 08/05/2016 15:27:26

08/05 16:17, , 11F
WatchService 通常會配一個雜湊檔...
08/05 16:17, 11F

08/05 16:19, , 12F
重點是WatchService是事件驅動 比THREAD省資源
08/05 16:19, 12F

08/05 16:21, , 13F
不過事件驅動的本質還是THREAD...
08/05 16:21, 13F

08/05 16:21, , 14F
其實你如果執行緒夠熟 也是能寫的
08/05 16:21, 14F

08/05 16:22, , 15F
看你用sleep硬幹就知道你應該不太熟
08/05 16:22, 15F

08/05 16:22, , 16F
建議你還是把WatchService弄熟比較快
08/05 16:22, 16F

08/05 16:24, , 17F
不好意思 沒看清楚 你第一個方法應該是去檢查兩邊
08/05 16:24, 17F

08/05 16:25, , 18F
檔案的MD5是不是一致這樣就好了
08/05 16:25, 18F

08/05 16:26, , 19F
檔案能否寫入跟OS實作FS的方式有關 所以這個方法不好
08/05 16:26, 19F
謝謝, 我對Thread 真的不熟...Orz 想請問檢查MD5 的部分是指 來源 跟 複製檔案的 md5 嗎? 比方說: c:\source\from.big.file.txt 跟 d:\des\from.big.file.txt 這兩個檔案的 md5 嗎? 還是 ? 謝謝您的回覆

08/05 17:09, , 20F
其實正本清源是要有protocol,以現在你描述的現況,你根本
08/05 17:09, 20F

08/05 17:09, , 21F
無法檢查何謂檔案copy好了. 必須有個明確的協定,例如使用
08/05 17:09, 21F

08/05 17:10, , 22F
者可先在其他暫存目錄建立好檔案,然後用move的方式,這樣
08/05 17:10, 22F

08/05 17:10, , 23F
目標目錄下的檔案一出現就是完整的. 又或者使用者copy完
08/05 17:10, 23F

08/05 17:11, , 24F
檔案,就touch一個特定格式檔名,這樣看到這個特定檔也可確
08/05 17:11, 24F

08/05 17:12, , 25F
定copy完成,這個標記用檔案處理完由你的程式刪除即可
08/05 17:12, 25F

08/05 17:14, , 26F
補充一下我所謂你無法確定檔案是否copy完了的意思是,除非
08/05 17:14, 26F

08/05 17:15, , 27F
你事先知道(或可計算)檔案完整長度,否則你無法確定檔案目
08/05 17:15, 27F

08/05 17:15, , 28F
前是已copy完成,還是對方程式只是剛好停頓檔案短時間沒再
08/05 17:15, 28F

08/05 17:16, , 29F
有內容變動
08/05 17:16, 29F
※ 編輯: love112302 (114.46.155.75), 08/05/2016 18:02:34 謝謝您~ 但是我沒有辦法要求使用者的動作 他們只想要把檔案拉進去這個資料夾就沒事了 Orz 我是有看到有人使用 File.length() 的方式, 然後幾秒沒有更新, 就判斷 File is ready 但是我在 WatchService 裡面用 Path.toFile().length() 每次都是 0 T___T ※ 編輯: love112302 (114.46.155.75), 08/05/2016 18:05:29

08/05 19:18, , 30F
你可以看一下File的API https://goo.gl/ChHnPB
08/05 19:18, 30F

08/05 19:19, , 31F
他有說有些情況會回傳0
08/05 19:19, 31F

08/05 19:49, , 32F
感覺像是網芳或者FTP這種單向的
08/05 19:49, 32F

08/05 19:50, , 33F
WatchService 一開始會檢測到CREATE事件 檔案傳完會
08/05 19:50, 33F

08/05 19:51, , 34F
檢測到MODIFY事件 其實這樣就蠻簡單了
08/05 19:51, 34F

08/05 19:53, , 35F
除非你規定他們傳檔時要有加個驗證檔案 MD5或SHA的
08/05 19:53, 35F

08/05 19:53, , 36F
這樣你後端就能檢查檔案完整性
08/05 19:53, 36F
謝謝, 想請問 即使是抓到 create 跟 modify 事件, 要如何判斷 因為我在最後一次觸發 Modify 的時候 去檢查檔案 File.canWrite() or File.length() 都沒有用 :(

08/05 23:08, , 37F
我覺得3的方式可行啊,1個thread大多數的時間在睡覺
08/05 23:08, 37F

08/05 23:08, , 38F
能吃什麼資源,不過多學WatchService也是好的。
08/05 23:08, 38F
但是就覺得是個技術債, 有一種遲早要還的感覺 XD 可能是因為死線還沒到 所以還不願意放行XD

08/05 23:12, , 39F
如果是別人做copy 不是就偵測copy的pie??
08/05 23:12, 39F
謝謝 我來研究一下這是什麼意思XD

08/06 19:00, , 40F
jej 提供的思路挺棒的
08/06 19:00, 40F
※ 編輯: love112302 (61.224.156.163), 08/07/2016 22:46:43

08/07 23:31, , 41F
我是根據其API來看的
08/07 23:31, 41F

08/07 23:31, , 42F
MODIFY的時機就是檔案被改寫
08/07 23:31, 42F

08/07 23:31, , 43F
那檔案什麼時候被改寫 FILE IO結束的時侯
08/07 23:31, 43F

08/07 23:32, , 44F
FILE IO什麼時候結束? 資料中斷或者寫完的時候
08/07 23:32, 44F

08/07 23:32, , 45F
所以我才會說如果是我所說的那種單向上傳
08/07 23:32, 45F

08/07 23:32, , 46F
你只能透過SHA或MD5來驗證檔案完整性
08/07 23:32, 46F

08/07 23:33, , 47F
WatchService只是監控IO的情況而已
08/07 23:33, 47F
※ 編輯: love112302 (61.224.156.163), 08/07/2016 23:36:17

08/25 00:52, , 48F
歡迎來看原始碼,稍候回文
08/25 00:52, 48F

08/27 22:40, , 49F
嘗試去lock檔案,其他程式copy當中你應該是不能lock的
08/27 22:40, 49F

08/27 22:40, , 50F
能lock就是copy完成了
08/27 22:40, 50F
文章代碼(AID): #1NetGifv (java)
文章代碼(AID): #1NetGifv (java)