不知道大家用過 Dropbox
沒有,這是國外一款非常好用云盤,你只需要在 Dropbox 中設置好要同步的目錄,每當此目錄中的文件發生變動時,Dropbox 就會自動把文件同步到云端。
那么,Dorpbox 是怎么知道目錄的文件發生了改變呢?答案是,通過 inotfiy
這個系統功能來實現的。
我們主要分為兩篇文章來介紹 inotify
這個功能:本篇首先介紹 inotify
的使用方式,而下篇主要介紹 inotify
的實現原理。
其實 inotify
的接口比較少,只有3個:inotify_init
、inotify_add_watch
和 inotify_rm_watch
。下面我們介紹一下這三個接口的作用和原型。
inotify_init
函數用于創建一個 inotify
的句柄,可以認為此句柄就是 inotify
的對象。其原型如下:
int inotify_init(void);
創建好 inotify
句柄后,就可以通過調用 inotify_add_watch
函數添加要進行監聽的文件或者目錄。其原型如下:
int inotify_add_watch(int fd, const char *path, uint32_t mask);
inotify_add_watch
調用成功后,會返回被監聽文件或目錄的描述符。下面介紹一下各個參數的意義:
fd
:就是通過 inotify_init
函數創建的 inotify
句柄。
path
:要監聽的文件或目錄的路徑。
mask
:要監聽的事件,其事件類型如下:
inotify_rm_watch
函數用于刪除被監聽的文件或目錄,其原型如下:
int inotify_rm_watch(int fd, uint32_t wd);
下面介紹一下各個參數的意義:
fd
:調用 inotify_init
函數返回的 inotify
句柄。wd
:由 inotify_add_watch
函數的返回被監聽文件或目錄的描述符。介紹完 inotify
的接口后,現在通過一個簡單的例子來展示怎么使用 inotify
。在編寫 inotify
的實例前,先介紹一下怎么獲取被監聽文件或目錄的變動事件。inotify
并沒有提供特定的接口來獲取被監聽的文件或目錄的變動事件,而是通過通用的 read
函數來讀取,我們來看看 read
函數的原型:
int read(int fd, void *events, size_t len);
下面說說各個參數的意義:
fd
:由 inotify_init
創建的 inotify
句柄。events
:存放變動事件的緩沖區。len
:緩沖區的大小。events
參數用于存放被監聽文件或目錄的變動事件,一般指定為 inotify_event
結構的數組,inotify_event
結構的定義如下:
struct inotify_event { int wd; // 被監控文件或目錄的描述符(由inotify_add_watch) uint32_t mask; // 變動的事件 uint32_t cookie; // 比較少使用,可以忽略 uint32_t len; // name的長度 char name[]; // 用于存放發生變動的文件或目錄名稱};
現在我們可以使用 inotify
來編寫實例了,這個實例主要介紹怎么使用 inotify
監聽一個文件或者目錄,并且打印其變動事件。
實現代碼如下:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/inotify.h> // 引入 inotify 的頭文件/** 用于打印發生的事件*/void display_event(const char *base, struct inotify_event *event){ char *operate; int mask = event->mask; if (mask & IN_ACCESS) operate = "ACCESS"; if (mask & IN_ATTRIB) operate = "ATTRIB"; if (mask & IN_CLOSE_WRITE) operate = "CLOSE_WRITE"; if (mask & IN_CLOSE_NOWRITE) operate = "CLOSE_NOWRITE"; if (mask & IN_CREATE) operate = "CREATE"; if (mask & IN_DELETE_SELF) operate = "DELETE_SELF"; if (mask & IN_MODIFY) operate = "MODIFY"; if (mask & IN_MOVE_SELF) operate = "MOVE_SELF"; if (mask & IN_MOVED_FROM) operate = "MOVED_FROM"; if (mask & IN_MOVED_TO) operate = "MOVED_TO"; if (mask & IN_OPEN) operate = "OPEN"; if (mask & IN_IGNORED) operate = "IGNORED"; if (mask & IN_DELETE) operate = "delete"; if (mask & IN_UNMOUNT) operate = "UNMOUNT"; printf("%s/%s: %sn", base, event->name, operate);}#define EVENTS_BUF_SIZE 4096int main(int argc, char const *argv[]){ int fd; int nbytes, offset; char events[EVENTS_BUF_SIZE]; struct inotify_event *event; fd = inotify_init(); // 創建 inotify 句柄 if (fd < 0) { printf("Failed to initalize inotifyn"); return -1; } // 從命令行參數獲取要監聽的文件或目錄路徑 // 添加要監聽的文件或者目錄, 監聽所有事件 if (inotify_add_watch(fd, argv[1], IN_ALL_EVENTS) == -1) { printf("Failed to add file or directory watchn"); return -1; } for (;;) { memset(events, 0, sizeof(events)); // 讀取發生的事件 nbytes = read(fd, events, sizeof(events)); if (nbytes <= 0) { printf("Failed to read eventsn"); continue; } // 開始打印發生的事件 for (offset = 0; offset < nbytes; ) { event = (struct inotify_event *)&events[offset]; // 獲取變動事件的指針 display_event(argv[1], event); offset += sizeof(struct inotify_event) + event->len; // 獲取下一個變動事件的偏移量 } } return 0;}
上面的實例邏輯比較簡單,主要步驟如下:
inotify_init
函數創建一個 inotify
句柄。inotify_add_watch
函數把其添加到 inotify
中進行監聽。read
函數讀取被監聽的文件或目錄的變動事件,并且通過調用 display_event
函數打印事件。上面實例比較難懂的就是從 events
參數中獲取變動事件的指針,我們可以通過下面這幅圖來理清獲取變動事件指針的邏輯:
通過上圖,就比較容易理解怎么從 events
緩沖區中獲取到變動事件的指針了。
最后,來看看我們編寫的實例的效果動畫:
本文主要介紹 inotify
的使用,在下一篇文章中,我們將會介紹 inotify
的原理和實現,敬請期待(當然對 inotify
的實現沒興趣的就不用期待了...)。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
babyq的功能是什么?Baby q是國內人工智能公司圖靈機器人的產品。在其官方網站上,該公司稱自己為“中國最智能的機器人大腦”。在與Q寶寶聊天的過程中,可以結合聊天前后的語境,回答問題,理解語境的語義。babyQ怎么關閉?首先,打開手機上的QQ,然后點擊下面的聯系板找到babyq2,點擊名片右上角的更多,然后關閉“接收babyq消息推送”滑塊。這樣,babyq智能合作伙伴將不會收到消息請按照以下...
平板上的英特爾z8500相當于臺式機什么級別的處理器?Intel z8500相當于臺式機E2100,因為在過去的五年中沒有這樣低性能的處理器。Z系列處理器是inter為上網本或平板電腦開發的超低功耗(約4W)處理器。你不能玩游戲。性能遠遠不夠,即使是lol級別最低的特效小網游,也卡爆了corem和z8700或z8500性能差距多大?差別很大。Z8700是471,比snapdragon 810好。Z...
濱海市屬于哪個省 濱海市屬于哪個???濱海和濱州是一個地方嗎? 濱海市是一個虛構的城市。濱海市經常出現在中國大量的影視劇中。它是中國文學小說和影視劇使用最頻繁的城市。使用虛構城市,避免誤解和對號入座?,F實中,天津濱海新區、江蘇省鹽城市濱??h、紹興市濱海區都有濱海兩個字。 濱海市屬于哪個??? 濱??h5個縣(響水縣、阜寧縣、射陽縣、建湖縣)之一,浙江省溫嶺市11個鎮(澤、大溪、松門、若橫、新河、...