文件系統(tǒng)監(jiān)控的踩坑實(shí)錄)
開場(chǎng)當(dāng)你興致勃勃地打開編輯器,按下保存鍵,期待熱重載的奇跡發(fā)生——結(jié)果編輯器直接崩潰,或者資源根本沒更新。這一幕在從零自研引擎時(shí)幾乎無法避免。最初我在 Linux 上用 inotify 跑通了文件監(jiān)控,信心滿滿移植到 Windows,發(fā)現(xiàn)ReadDirectoryChangesW的行為模式完全不同;再到 macOS,F(xiàn)SEvents 又是一套獨(dú)立 API。三套代碼、三種語義、三種坑位——這不是偶然,而是三套 API 在內(nèi)核里各自長在完全不同的機(jī)制上。更麻煩的是,資源管線、游戲邏輯、序列化系統(tǒng)全都依賴這個(gè)監(jiān)聽器,它吐出一個(gè)錯(cuò)誤事件,上層一切跟著翻車。下面先講清「為什么三個(gè)系統(tǒng)長得不一樣」,再逐個(gè)拆坑,最后給出一套能用的抽象層設(shè)計(jì)。一、為什么三套 API 差異這么大文件監(jiān)控不是"操作系統(tǒng)提供的標(biāo)準(zhǔn)功能",而是各內(nèi)核在不同歷史背景下長出來的不同機(jī)制,理解它們的出身,才能理解行為的差異:Linux inotify:掛在 inode 上的觀察點(diǎn)(watch)。你監(jiān)視的是"這個(gè)目錄這個(gè) inode 上發(fā)生的事件",所以它天然不遞歸——子目錄是另一個(gè) inode,想監(jiān)視得自己挨個(gè)加 watch。事件帶 cookie 字段,專門為配對(duì) rename 設(shè)計(jì)。Windows ReadDirectoryChangesW:基于目錄變更通知 + IRP(I/O Request Packet)。你提交一個(gè)緩沖區(qū)給系統(tǒng),系統(tǒng)把變更記錄填進(jìn)去還給你。它天然