這很難完成的部分是掃描目錄,只是因爲它可能很昂貴。
但這是一個殘酷的現實,因爲你不能使用inotify等人。
在你的數據庫,只需創建一個節點類型的記錄:
create table node (
nodeKey integer not null primary key,
parentNode integer references node(nodeKey), // allow null for the root, or have root point to itself, whatever
fullPathName varchar(2048),
nodeName varchar(2048),
nodeType varchar(1) // d = directory, f = file, or whatever else you want
)
這就是你的節點結構。
您可以使用完整路徑列以絕對路徑快速查找任何內容。
當文件移動時,只需重新計算路徑即可。
最後,掃描你的音樂文件。在unix中,你可以這樣做:
找到。 -type f | sort> sortedListOfFiles
接下來,只需將所有路徑名稱從數據庫中抽取出來即可。從節點
選擇fullPathName其中節點類型!通過fullPathName
=「d」訂單現在你有兩份文件的排序列表。
通過DIFF(或comm)運行它們,您將獲得已刪除文件和新文件的列表。您將不會有「移動」文件的列表。如果你想對新舊文件進行比較,並且它們具有相同的結尾(即.... /專輯/歌曲)來嘗試檢測「移動」與新舊版本的比較,那麼很好,沒什麼大不了的。值得一試。
但差異會給你你的心跳差異。
如果你有很多文件,那麼,很抱歉,這需要一些時間 - 但你已經知道當你失去inotify功能時。如果你有這樣做,那只是增量維護。
當一個文件移動時,找到它的新絕對路徑是微不足道的,因爲你可以向它的父路徑詢問它的路徑,並簡單地將你的名字附加到它。之後,除非你想要,否則你不會爬樹或任何東西。雙向工作。
附錄:
如果你想跟蹤實際名稱的變化,就可以得到多一點的信息。
你可以這樣做:
find . -type f -print0 | xargs -0 ls -i | sort -n > sortedListOfFileWithInode
的-print0和-0使用帶空格的文件工作。然而文件名中的引號會破壞這個。通過python和fstat運行原始列表來獲得inode可能會更好。你可以在這裏做不同的事情。
這是做什麼而不是隻有名稱,你也可以得到文件的inode。 inode是「真實」文件,目錄將名稱鏈接到inode。這是如何在unix文件系統中將多個名稱(硬鏈接)分配給單個文件,所有名稱都指向同一個inode。
當文件重命名時,inode將保持不變。在unix中,有一個命令用於重命名和移動文件mv。當mv重命名或移動文件時,inode與文件在同一文件系統上保持一樣。
因此,使用inode以及文件名可以讓您捕獲一些更有趣的信息,如文件移動。
如果他們刪除文件並添加一個新文件,這將毫無幫助。但是你可能會(可能)能夠知道它發生了,因爲舊的inode不太可能被重新用於新的inode。
所以,如果你有文件的列表(按文件名排序):
1234 song1.mp3
1235 song2.mp3
1236 song3.mp3
,有人刪除並重新添加歌曲2,你必須像
1234 song1.mp3
1237 song2.mp3
1236 song3.mp3
但如果你這樣做:
mv song1.mp3 song4.mp3
您將獲得:
1237 song2.mp3
1236 song3.mp3
1234 song4.mp3
另一個需要注意的是,如果您失去了驅動器並從備份中恢復,很可能所有的inode都會發生變化,從而強制重建索引。
如果您真的冒險,可以嘗試使用擴展文件系統屬性進行播放,並將其他感興趣的元數據分配給文件。雖然沒有做太多的事情,但它也有可能性,並且有可能看不到的危險,但是...
爲什麼會被O您最初的想法(N^2)?假設數據庫在歌曲名稱上有一個O(log n)索引(應該很容易安排),它應該是O(n log n)。 – andrewdski
如果你很擔心複雜性,你可以使用'O(n)'作爲'n'查找/更新的散列。 –
我第二個哈希的想法;唯一的問題是,你如何決定一個獨特的密鑰來哈希?我不會去任何正常的文件屬性,因爲這些可以改變。也許根據文件中的樣本製作一個關鍵字? –