MacOS文件監(jiān)控

概述

在File System 事件中,當文件目錄層次結(jié)構(gòu)的內(nèi)容發(fā)生變化時,獲取通知。即提供了監(jiān)聽文件功能。

文件系統(tǒng)事件API提供了一種方法,讓應(yīng)用程序在目錄層次結(jié)構(gòu)的內(nèi)容被修改時請求通知。例如,您的應(yīng)用程序可以使用它來快速檢測用戶何時使用另一個應(yīng)用程序修改了項目包中的文件。
它還提供了一種輕量級的方法來確定自應(yīng)用程序上次檢查目錄層次結(jié)構(gòu)的內(nèi)容之后,目錄層次結(jié)構(gòu)的內(nèi)容是否發(fā)生了更改。例如,備份應(yīng)用程序可以使用它來確定自給定時間戳或給定事件ID以來哪些文件發(fā)生了更改。

相關(guān)API翻譯

1.FSEventStreamCreate

使用給定的參數(shù)創(chuàng)建一個新的FS事件流對象,為了可以接受事件通知,必須調(diào)用FSEventStreamScheduleWithRunLoop()FSEventStreamStart()函數(shù)。

allocator:用于為流分配內(nèi)存,可以通過NULL或者kCFAllocatroDefault來使用當前默認值。

callBack:FS事件發(fā)生時,一個函數(shù)回調(diào)。

context:指向客戶端的 FSEventStreamContext 結(jié)構(gòu)的指針
它會與這個流相關(guān)聯(lián)。然后它的字段被復(fù)制出來進入流本身,以便在創(chuàng)建流后可以釋放其內(nèi)存。允許傳遞 NULL 如果傳遞NULL則等同于傳遞一個字段都設(shè)置為零的結(jié)構(gòu)。

pathsToWatch:每個CFStringRef指定一個目錄的路徑,表示要監(jiān)視修改的文件系統(tǒng)層次結(jié)構(gòu)的根。

sinceWhen:該服務(wù)將提供在給定事件id之后發(fā)生的事件。通常,客戶端會提供他們在回調(diào)中收到的最高編號FSEventStreamEventId,他們可以通過 FSEventStreamGetLatestEventId()訪問器來獲取,不要傳0值,除非你想接受自“時間開始”以來修改的每一個目錄事件。

latency:服務(wù)在從內(nèi)核得知某個事件后,通過回調(diào)將其傳遞給客戶端之前,應(yīng)該等待的秒數(shù)。指定較大的值可能會導致更有效的臨時合并,從而減少回調(diào),提高總體效率。如果為10s,則10s交付一次事件。

flag:修改正在創(chuàng)建的流的行為的標志,具體可以看FSEventStreamCreateFlags枚舉

func FSEventStreamCreate(_ allocator: CFAllocator?, _ callback: FSEventStreamCallback, _ context: UnsafeMutablePointer<FSEventStreamContext>?, _ pathsToWatch: CFArray, _ sinceWhen: FSEventStreamEventId, _ latency: CFTimeInterval, _ flags: FSEventStreamCreateFlags) -> FSEventStreamRef?

2.FSEventStreamCopyDescription

傳入一個事件流,包含所提供流的描述的CFStringRef,

func FSEventStreamCopyDescription(_ streamRef: ConstFSEventStreamRef) -> CFString

例如:我傳入一個FSEventStreamRef,它的描述如下

FSEventStreamRef @ 0x11ef04d40:
   allocator = 0x1f1cd88c0
   callback = 0x100c7aa74
   context = {0, 0x600000294c80, 0x0, 0x0, 0x0}
   numPathsToWatch = 1
   pathsToWatch = 0x600002e9c210
        pathsToWatch[0] = '/System/Volumes/Data/Users/wzf/Desktop/test1'
   latestEventId = 5642644
   latency = 1000000 (microseconds)
   flags = 0x00000011
    runLoop = 0x600001084400
    runLoopMode = 0x1f1ce52a8

3.FSEventStreamCopyPathsBeingWatched

返回創(chuàng)建流時提供的那些目錄路徑

func FSEventStreamCopyPathsBeingWatched(_ streamRef: ConstFSEventStreamRef) -> CFArray

示例如下:

po FSEventStreamCopyPathsBeingWatched(self.syncEventStream)
<__NSSingleObjectArrayI 0x600002e9c3a0>(
/Users/wzf/Desktop/test1

4.FSEventStreamCreateRelativeToDevice

使用給定的參數(shù)為特定設(shè)備創(chuàng)建一個新的FS事件流對象。與FSEventStreamCreate相比,它可以指定一個特定的設(shè)備去監(jiān)聽。

deviceToWatch:dev_t對應(yīng)于您想要收到通知的設(shè)備,dev_t與該設(shè)備上文件stat結(jié)構(gòu)中的st_dev字段或者statfs結(jié)構(gòu)中的f_fsid[0]字段相同。如果dev的值為0,則忽略。

pathsToWatchRelativeToDevice: 每個目錄路徑為指定設(shè)備的dev參數(shù)標識的目錄的相對路徑。路徑應(yīng)該相對于設(shè)備的根。例如,如果一個卷“MyData”掛載在“/Volumes/MyData”,而你想要觀看“/Volumes/MyData/Pictures/July”,則需要指定一個路徑字符串“Pictures/July”。要觀察一個卷的根通過一個路徑“”(空字符串)。。

func FSEventStreamCreateRelativeToDevice(_ allocator: CFAllocator?, _ callback: FSEventStreamCallback, _ context: UnsafeMutablePointer<FSEventStreamContext>?, _ deviceToWatch: dev_t, _ pathsToWatchRelativeToDevice: CFArray, _ sinceWhen: FSEventStreamEventId, _ latency: CFTimeInterval, _ flags: FSEventStreamCreateFlags) -> FSEventStreamRef?

5.FSEventStreamFlushAsync

根據(jù)FS事件流對象返回一個最大的事件id,如果流中沒有事件排隊,則為0。

要求FS Events服務(wù)清除已發(fā)生但由于在創(chuàng)建流時提供的延遲參數(shù)而尚未交付的任何事件。由于此刷新是異步發(fā)生的——不保證在此調(diào)用完成時,事件已經(jīng)交付給回調(diào)監(jiān)聽函數(shù)。

注意:這個函數(shù)必須在FSEventStreamStart()之后調(diào)用。

func FSEventStreamFlushAsync(_ streamRef: FSEventStreamRef) -> FSEventStreamEventId

示例:

po FSEventStreamFlushAsync(self.syncEventStream)
5858865

6.FSEventStreamFlushSync

要求FS Events服務(wù)清除已發(fā)生但由于在創(chuàng)建流時提供的延遲參數(shù)而尚未交付的任何事件。這個刷新是同步發(fā)生的——所以當這個調(diào)用返回時,已經(jīng)發(fā)生的事件會回調(diào)給監(jiān)聽函數(shù)。

注意:這個函數(shù)必須在FSEventStreamStart()之后調(diào)用。

FSEventStreamFlushSync(_ streamRef: FSEventStreamRef)

7.FSEventStreamGetDeviceBeingWatched

獲取FSEventStreamCreateRelativeToDevice創(chuàng)建流時提供的dev_t,否則為0。

func FSEventStreamGetDeviceBeingWatched(_ streamRef: ConstFSEventStreamRef) -> dev_t

8.FSEventStreamGetLatestEventId

獲取流的sinceWhen屬性。在接收到事件時(在調(diào)用客戶端回調(diào)之前),此屬性將被更新為事件中提到的最高編號的事件ID。

func FSEventStreamGetLatestEventId(_ streamRef: ConstFSEventStreamRef) -> FSEventStreamEventId

9.FSEventStreamInvalidate(_:)

使FSEventStreamRef無效,就像CFRunLoopSourceInvalidate()對CFRunLoopSourceRef所做的那樣。它將從任何已調(diào)度的運行循環(huán)或調(diào)度隊列中取消調(diào)度。

注意:FSEventStreamInvalidate()只能在調(diào)用FSEventStreamScheduleWithRunLoop或者FSEventStreamSetDispatchQueue()之后

10.FSEventStreamRelease(_:)

減少流的引用計數(shù)。refcount最初是1,F(xiàn)SEventStreamRetain()遞增。如果引用計數(shù)達到零,則釋放流。

func FSEventStreamRelease(_ streamRef: FSEventStreamRef)

11.FSEventStreamRetain(_:)

遞增流的引用計數(shù)

func FSEventStreamRetain(_ streamRef: FSEventStreamRef)

12.FSEventStreamScheduleWithRunLoop(::_:)

這個函數(shù)在指定的運行循環(huán)上調(diào)度流,就像CFRunLoopAddSource()對CFRunLoopSourceRef所做的那樣。調(diào)用方負責確保流至少在一個運行循環(huán)中被調(diào)度,并且至少在調(diào)度流的運行循環(huán)中被運行。如果要開始接收流上的事件,則調(diào)用FSEventStreamStart()。
要從已調(diào)度的運行循環(huán)中刪除流,請調(diào)用FSEventStreamUnscheduleFromRunLoop或FSEventStreamInvalidate()。

func FSEventStreamScheduleWithRunLoop(_ streamRef: FSEventStreamRef, _ runLoop: CFRunLoop, _ runLoopMode: CFString)

13.FSEventStreamSetDispatchQueue

此函數(shù)在指定的隊列上調(diào)度流。調(diào)用方負責確保流被調(diào)度到調(diào)度隊列上,并且隊列已經(jīng)啟動。如果在隊列上調(diào)度流有問題,則在嘗試啟動流時將返回錯誤。

要開始接收流上的事件,調(diào)用FSEventStreamStart()。

要從調(diào)度流的指定隊列中刪除流,則調(diào)用FSEventStreamInvalidate()

注意:不要設(shè)置隊列為NULL,如果為NULL則不能調(diào)用FSEventStreamInvalidatee()去使流無效。否則會發(fā)生錯誤!

func FSEventStreamSetDispatchQueue(_ streamRef: FSEventStreamRef, _ q: DispatchQueue?)

14.FSEventStreamSetExclusionPaths(::)

設(shè)置從EventStream中過濾的目錄。最多可以指定8個目錄。

func FSEventStreamSetExclusionPaths(_ streamRef: FSEventStreamRef, _ pathsToExclude: CFArray) -> Bool

15.FSEventStreamShow(_:)

將所提供流的描述打印到標準錯誤。僅供調(diào)試。

func FSEventStreamShow(_ streamRef: ConstFSEventStreamRef)

示例:

(lldb) po FSEventStreamShow(self.syncEventStream)
FSEventStreamRef @ 0x129004e20:
   allocator = 0x1f1cd88c0
   callback = 0x10411ea68
   f2d_private_port = 0x13903
   context = {0, 0x6000035e6300, 0x0, 0x0, 0x0}
   numPathsToWatch = 1
   pathsToWatch = 0x6000019e0080
        pathsToWatch[0] = '/'
   numPathsToExclude = 0
   latestEventId = 6270384
   latency = 1000000000 (microseconds)
   flags = 0x00000011
   runLoop = 0x6000027e4200
   runLoopMode = 0x1f1ce52a8
(lldb) 

16.FSEventStreamStart(_:)

嘗試向FS Events服務(wù)注冊,以接收流中每個參數(shù)的事件。
只有當流在至少一個運行循環(huán)上被調(diào)度時(FSEventStreamScheduleWithRunLoop),才可以調(diào)用FSEventStreamStart()。
一旦啟動,流可以通過FSEventStreamStop()停止。

func FSEventStreamStart(_ streamRef: FSEventStreamRef) -> Bool

17.FSEventStreamStop(_:)

取消向FS Events服務(wù)注冊。當流停止時,客戶端回調(diào)將不會被調(diào)用。
只有在流已經(jīng)啟動時(調(diào)用FSEventStreamStart啟動),才可以調(diào)用FSEventStreamStop。
一旦停止,流可以通過FSEventStreamStart重新啟動,此時它將繼續(xù)接收從它停止的地方("sinceWhen")接收的事件。

func FSEventStreamStop(_ streamRef: FSEventStreamRef)

18.FSEventStreamUnscheduleFromRunLoop

這個函數(shù)從指定的運行循環(huán)中刪除流,就像CFRunLoopRemoveSource()對CFRunLoopSourceRef所做的那樣。

func FSEventStreamUnscheduleFromRunLoop(_ streamRef: FSEventStreamRef, _ runLoop: CFRunLoop, _ runLoopMode: CFString)

19.FSEventsCopyUUIDForDevice(_:)

獲取與設(shè)備關(guān)聯(lián)的UUID.如果為NULL(例如,在只讀設(shè)備上)。UUID(非null)唯一標識給定的FSEvents流。如果這個(非null) UUID與上一次運行中存儲的UUID不同,那么事件流也不同(例如,因為清除了FSEvents,因為磁盤被擦除,或者因為事件ID計數(shù)器被包裝回零)。
一個NULL返回值表明“歷史的”事件是不可用的,也就是說,你不應(yīng)該提供一個“sinceWhen”值給FSEventStreamCreate(),除了kFSEventStreamEventIdSinceNow。
也就是在第一次初始化FSEventStreamCreate的時候,應(yīng)該sinceWhen傳kFSEventStreamEventIdSinceNow,之后的值就傳存儲在本地的sinceWhen(鑰匙串或者偏好設(shè)置)

func FSEventsCopyUUIDForDevice(_ dev: dev_t) -> CFUUID?

20.FSEventsGetCurrentEventId()

獲取最近生成的事件ID,在系統(tǒng)范圍內(nèi)(不只是一個流)。當它返回到應(yīng)用程序時,甚至可能已經(jīng)生成了更新的事件。
如果currentId = 上一次id + 1,文件可能被重命名或者移動了。

func FSEventsGetCurrentEventId() -> FSEventStreamEventId

21.FSEventsGetLastEventIdForDeviceBeforeTime(::)

獲取給定設(shè)備在給定時間之前返回的最后一個事件ID。這是一種保守的做法,如果您隨后使用返回的事件ID作為FSEventStreamCreateRelativeToDevice()的sinceWhen參數(shù),那么您將不會錯過自那時以來發(fā)生的任何事件。另一方面,您可能會收到一些(無害的)額外事件。

注意:有一些事情可能會導致這個不準確。例如,有人可能會更改系統(tǒng)的時鐘(向后或向前)?;蛘撸跊]有完全同步時鐘的情況下,外部驅(qū)動器也可以用于不同的系統(tǒng)。

22.FSEventsPurgeEventsForDeviceUpToEventId(::)

從服務(wù)維護的每卷持久化數(shù)據(jù)庫中清除舊事件。只能由root用戶調(diào)用。

func FSEventsPurgeEventsForDeviceUpToEventId(_ dev: dev_t, _ eventId: FSEventStreamEventId) -> Bool

23.FSEventStreamCreateFlags

傳遞給FSEventStreamCreatee…()函數(shù),表示正在創(chuàng)建的流的行為標志

23.1 kFSEventStreamCreateFlagNone = 0x00000000 默認值

23.2 kFSEventStreamCreateFlagUseCFTypes = 0x00000001

框架將使用CF類型而不是原始的C類型(例如,CFStringRefs的CFArrayRef,而不是原始C字符串指針的原始C數(shù)組)調(diào)用你的回調(diào)函數(shù)

23.3 kFSEventStreamCreateFlagNoDefer = 0x00000002

重置創(chuàng)建FS流對象的延遲計時器,使之無效。

如果你指定了這個標志,并且從最后一個事件開始超過了延遲秒,你的應(yīng)用程序?qū)⒘⒓唇邮盏竭@個事件。事件的傳遞將重置延遲計時器,任何后續(xù)事件都將在延遲數(shù)秒過后傳遞。這個標志對于那些交互性強、希望對變化立即做出反應(yīng)、但避免在變化頻繁發(fā)生時被通知淹沒的應(yīng)用很有用。

如果不指定此標志,則在一段時間無事件之后發(fā)生事件時,將啟動延遲計時器。在下一個延遲秒內(nèi)發(fā)生的任何事件都將作為一個組交付(包括第一個事件)。事件組的傳遞將重置延遲計時器,任何進一步的事件將在延遲秒之后傳遞。這是默認行為,更適合于后臺、守護程序或批處理應(yīng)用程序。

23.4 kFSEventStreamCreateFlagWatchRoot = 0x00000004

請求沿著路徑向您正在觀察的路徑發(fā)出變更通知。例如,使用這個標志,如果你監(jiān)聽的文件路徑為“/foo/bar”并將其重命名為“/foo/bar.old”。,你會收到一個RootChanged事件。如果目錄"/foo"被重命名,也是同樣的情況。您接收到的事件是一個特殊事件:事件的路徑是您指定的原始路徑,設(shè)置了標志kFSEventStreamEventFlagRootChanged并且事件ID為零。
RootChanged事件在指示您應(yīng)該重新掃描特定的層次結(jié)構(gòu)時很有用,因為它已經(jīng)完全更改了(而不是其中的內(nèi)容在更改)。
如果希望跟蹤目錄的當前位置,最好在創(chuàng)建流之前打開目錄,以便為它提供一個文件描述符,并可以發(fā)出F_GETPATH fcntl()來查找當前路徑。

23.5 kFSEventStreamCreateFlagIgnoreSelf __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_6_0) = 0x00000008

不要發(fā)送由當前進程觸發(fā)的事件。
這對于減少發(fā)送的事件量很有用。只有當您的進程可能修改正在監(jiān)視的路徑下的文件系統(tǒng)層次結(jié)構(gòu)時,它才有用。

注意:這對歷史事件沒有影響,即那些在HisoryDone哨兵事件之前交付的事件。而且,這并不適用于RootChanged事件,因為WatchRoot特性使用了一種獨立的機制,無法提供有關(guān)所負責進程的信息。

23.6 kFSEventStreamCreateFlagFileEvents __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00000010

請求文件級別通知。你的流將接收關(guān)于你正在觀察的層次結(jié)構(gòu)中的單個文件的事件,而不僅僅是接收目錄級別的通知。使用此標志時要小心,因為它將生成比沒有它時多得多的事件。

23.7 kFSEventStreamCreateFlagMarkSelf __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) = 0x00000020

用“OwnEvent”標記當前進程觸發(fā)的事件。只有當您的進程可能修改正在監(jiān)視的路徑下的文件系統(tǒng)層次結(jié)構(gòu),并且您希望知道您的進程觸發(fā)了哪些事件時,這才有用。

注意:這對歷史事件沒有影響,即那些在HistoryDone哨兵事件之前交付的事件。

23.8 kFSEventStreamCreateFlagUseExtendedData __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0) = 0x00000040

需要kFSEventStreamCreateFlagUseCFTypes,并指示框架使用CF類型調(diào)用你的回調(diào)函數(shù),但不是傳遞CFArrayRef的CFArrayRef,而是傳遞CFDictionaryRefs的CFArrayRef。每個字典將包含事件路徑和可能的其他關(guān)于事件的“擴展數(shù)據(jù).

24.FSEventStreamEventFlags

可以傳遞給您的 FSEventStreamCallback函數(shù)的標志。重要的是要注意,事件標志只是關(guān)于在該路徑上發(fā)生的操作類型的提示。

24.1 kFSEventStreamEventFlagNone = 0x00000000

此事件中提供的特定路徑處的目錄發(fā)生了一些更改

24.2 kFSEventStreamEventFlagMustScanSubDirs = 0x00000001

您的應(yīng)用程序不僅必須重新掃描事件中給定的目錄,還必須遞歸地重新掃描其所有子目錄。如果出現(xiàn)事件分層合并的問題,就會發(fā)生這種情況。例如,/Users/jsmith/Music 中的一個事件和 /Users/jsmith/Pictures中的一個事件可能會合并為一個設(shè)置了此標志且 path=/Users/jsmith的事件。如果設(shè)置了此標志,您可以通過檢查信息標志kFSEventStreamEventFlagUserDropped 或 kFSEventStreamEventFlagKernelDropped.

24.3 kFSEventStreamEventFlagUserDropped = 0x00000002

除了 kFSEventStreamEventFlagMustScanSubDirs 標志外,還可以設(shè)置 kFSEventStreamEventFlagUserDropped 或 kFSEventStreamEventFlagKernelDropped 標志,以指示在緩沖事件時出現(xiàn)問題(特定標志集指示問題發(fā)生的位置)并且客戶端必須對任何目錄進行全面掃描(和它們的子目錄,遞歸地)被這個流監(jiān)視。如果您要求使用此流監(jiān)視多個路徑,那么您將收到有關(guān)所有路徑的通知。您的代碼只需要檢查 kFSEventStreamEventFlagMustScanSubDirs標志;這些標志(如果存在)僅提供幫助您診斷問題的信息。

24.4 kFSEventStreamEventFlagKernelDropped = 0x00000004

如果設(shè)置了 kFSEventStreamEventFlagEventIdsWrapped,這意味著 64 位事件 ID 計數(shù)器環(huán)繞。因此,先前發(fā)布的事件 ID 不再是 FSEventStreamCreate...() 函數(shù)的 sinceWhen 參數(shù)的有效參數(shù)。

24.5 kFSEventStreamEventFlagEventIdsWrapped = 0x00000008

如果設(shè)置了 kFSEventStreamEventFlagEventIdsWrapped,這意味著 64 位事件 ID 計數(shù)器環(huán)繞。因此,先前發(fā)布的事件 ID 不再是 FSEventStreamCreate...() 函數(shù)的 sinceWhen 參數(shù)的有效參數(shù)。

24.6 kFSEventStreamEventFlagHistoryDone = 0x00000010

表示發(fā)送的標記事件以標記“歷史”事件的結(jié)束由于在創(chuàng)建此事件流的 FSEventStreamCreate...() 調(diào)用中指定了一個 sinceWhen 值而發(fā)送。(如果 kFSEventStreamEventIdSinceNow被傳遞給sinceWhen,它不會被發(fā)送。)在使用之前發(fā)生的所有“歷史”事件調(diào)用客戶端的回調(diào)之后,將使用設(shè)置了kFSEventStreamEventFlagHistoryDone 標志的事件調(diào)用客戶端的回調(diào)??蛻舳藨?yīng)忽略此回調(diào)中提供的路徑。

24.7 kFSEventStreamEventFlagRootChanged = 0x00000020

表示當您要求觀看的目錄之一的路徑上的目錄之一發(fā)生更改時發(fā)送的特殊事件。設(shè)置此標志后,事件 ID 為零,并且路徑對應(yīng)于您要求觀看的路徑之一(特別是更改的路徑)。該路徑可能不再存在,因為它或其父路徑之一已被刪除或重命名。只有當您在創(chuàng)建流時將標志 kFSEventStreamCreateFlagWatchRoot 傳遞給 FSEventStreamCreate...() 時,才會發(fā)送設(shè)置了此標志的事件。

24.8 c = 0x00000040

表示在其中一個路徑下安裝卷時發(fā)送的特殊事件被監(jiān)控。事件中的路徑是新安裝的卷的路徑。對于內(nèi)核中的每個卷掛載事件,您都會收到這些通知之一(獨立于DiskArbitration)。請注意,新安裝的卷可能包含任意大的目錄層次結(jié)構(gòu)。避免諸如觸發(fā)非本地文件系統(tǒng)的遞歸掃描之類的陷阱,您可以通過檢查 statfs() 返回的 f_flags 中是否缺少 MNT_LOCAL 標志來檢測。還請注意為不應(yīng)由用戶界面元素顯示的卷設(shè)置的 MNT_DONTBROWSE 標志。

24.9 kFSEventStreamEventFlagUnmount = 0x00000080

表示在被監(jiān)視的路徑之一下卸載卷時發(fā)送的特殊事件。事件中的路徑是卸載卷的目錄的路徑。對于內(nèi)核中的每個卷卸載事件,您都會收到這些通知之一。這不能替代 DiskArbitration 框架提供的通知;您只會在卸載發(fā)生后收到通知。請注意,卸載卷可能會發(fā)現(xiàn)任意大的目錄層次結(jié)構(gòu),盡管 Mac OS X 永遠不會這樣做。

24.10 kFSEventStreamEventFlagItemCreated __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00000100

在此事件中提供的特定路徑上創(chuàng)建了文件系統(tǒng)對象。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.11 kFSEventStreamEventFlagItemRemoved __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00000200

在此事件中提供的特定路徑中刪除了文件系統(tǒng)對象。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.12 kFSEventStreamEventFlagItemInodeMetaMod __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00000400

此事件中提供的特定路徑上的文件系統(tǒng)對象已修改其元數(shù)據(jù)。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.13 kFSEventStreamEventFlagItemRenamed __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00000800

在此事件中提供的特定路徑中重命名了文件系統(tǒng)對象。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.14 kFSEventStreamEventFlagItemModified __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00001000

此事件中提供的特定路徑上的文件系統(tǒng)對象已修改其數(shù)據(jù)。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.15 kFSEventStreamEventFlagItemFinderInfoMod __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00002000

此事件中提供的特定路徑上的文件系統(tǒng)對象已修改其 FinderInfo 數(shù)據(jù)。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.16 kFSEventStreamEventFlagItemChangeOwner __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00004000

此事件中提供的特定路徑上的文件系統(tǒng)對象的所有權(quán)已更改。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.17 kFSEventStreamEventFlagItemXattrMod __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00008000

此事件中提供的特定路徑上的文件系統(tǒng)對象已修改其擴展屬性。(僅當您在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.18 kFSEventStreamEventFlagItemIsFile __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00010000

此事件中提供的特定路徑上的文件系統(tǒng)對象是常規(guī)文件。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.19 kFSEventStreamEventFlagItemIsDir __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00020000

此事件中提供的特定路徑上的文件系統(tǒng)對象是一個目錄。(只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.20 kFSEventStreamEventFlagItemIsSymlink __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_6_0) = 0x00040000

此事件中提供的特定路徑上的文件系統(tǒng)對象是符號鏈接。(僅當您在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.21 kFSEventStreamEventFlagOwnEvent __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) = 0x00080000

表示事件是由當前進程觸發(fā)的。(只有在創(chuàng)建流時指定了 MarkSelf 標志時才會設(shè)置此標志。)

24.22 kFSEventStreamEventFlagItemIsHardlink __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_9_0) = 0x00100000

表示此事件中提供的指定路徑上的對象是硬鏈接。(只有在創(chuàng)建流時指定了 FileEvents 標志時才會設(shè)置此標志。)

24.23 kFSEventStreamEventFlagItemIsLastHardlink __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_9_0) = 0x00200000

表示此事件中提供的特定路徑上的對象是最后一個硬鏈接。(僅當您在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

24.24 kFSEventStreamEventFlagItemCloned __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0) = 0x00400000

此事件中提供或提供的特定路徑上的文件系統(tǒng)對象是克隆的. (只有在創(chuàng)建流時指定 FileEvents 標志時才會設(shè)置此標志。)

25.FSEventStreamCallback

這是客戶端在創(chuàng)建新流時提供的回調(diào)函數(shù)的類型。當事件發(fā)生時,服務(wù)根據(jù)創(chuàng)建流時指定的參數(shù)從客戶端運行循環(huán)調(diào)用此回調(diào)。
streamRef:事件發(fā)生的流。

clientCallBackInfo:創(chuàng)建此流時在上下文中提供的信息字段。

numEvents:在這個回調(diào)中報告的事件數(shù)。每個數(shù)組(eventPaths, eventFlags, evententids)都有這么多元素。

eventPaths:事件發(fā)生所在目錄的路徑數(shù)組。這個參數(shù)的類型取決于傳遞給FSEventStreamCreate…()的標志。如果設(shè)置了kFSEventStreamCreateFlagUseCFTypes,那么這將是一個包含CFStringRef對象的CFArrayRef(每個CFStringCreateWithFileSystemRepresentation())。所有權(quán)遵循Get規(guī)則,它們將在你的回調(diào)返回后由框架釋放。如果kFSEventStreamCreateFlagUseCFTypes沒有設(shè)置,那么框架將傳遞給你的回調(diào)一個原始C字符串的原始C數(shù)組,在你的回調(diào)返回后,框架將被釋放。

eventFlags:對應(yīng)于eventPaths參數(shù)中的路徑的行為標識(創(chuàng)建、刪除、重命名等)數(shù)組。如果沒有設(shè)置標志,則在此事件中提供的特定路徑上的目錄中有一些更改。

eventIds:一個FSEventStreamEventIds數(shù)組,對應(yīng)于eventPaths參數(shù)中的路徑。
每個事件ID來自在eventPaths參數(shù)中命名的相應(yīng)目錄中報告的最近的事件。事件id都來自一個全局源。它們保證總是在增加,通常是跳躍式增長,甚至跨越系統(tǒng)重新啟動和將驅(qū)動器從一臺機器移動到另一臺機器。就在調(diào)用回調(diào)之前,你的流被更新,以便調(diào)用訪問器FSEventStreamGetLatestEventId時將返回在eventIds參數(shù)中傳遞的最大值;如果你要在回調(diào)之后停止處理這個流中的事件,并在稍后從新創(chuàng)建的FSEventStream中繼續(xù)處理它們,這是你要傳遞給fsevenstreamcreate…()函數(shù)的sinceWhen參數(shù)的值。最好把id存在本地。

typealias FSEventStreamCallback = (ConstFSEventStreamRef, UnsafeMutableRawPointer?, Int, UnsafeMutableRawPointer, UnsafePointer<FSEventStreamEventFlags>, UnsafePointer<FSEventStreamEventId>) -> Void

應(yīng)用

可以參閱: MacOS 開發(fā) - FSEventStream(文件系統(tǒng)改變事件監(jiān)控)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容