1. 程式人生 > >Inotify與Android檔案監控FileObserver原理

Inotify與Android檔案監控FileObserver原理

概要 - 為什麼需要監控檔案系統?

在日常工作中,人們往往需要知道在某些檔案(夾)上都有那些變化,比如:

  • 通知配置檔案的改變
  • 跟蹤某些關鍵的系統檔案的變化
  • 監控某個分割槽磁碟的整體使用情況
  • 系統崩潰時進行自動清理
  • 自動觸發備份程序
  • 向伺服器上傳檔案結束時發出通知

通常使用檔案輪詢的通知機制,但是這種機制只適用於經常改變的檔案(因為它可以確保每過x秒就可以得到i/o),其他情況下都非常低效,並且有時候會丟失某些型別的變化,例如檔案的修改時間沒有改變。像Tripwire這樣的資料完整性系統,它們基於時間排程來跟蹤檔案變化,但是如果想實時監控檔案的變化的話,那麼時間排程就束手無策了。Inotify就這樣應運而生了。本文將簡要介紹inotify,告訴我們如何監控資料夾,如何一有變化就報告相關訊息事件,並介紹了一些相關工具, 我們可以把它們新增到自己的工具箱中。

Inotify到底是什麼?

Inotify是一種檔案變化通知機制,Linux核心從2.6.13開始引入。在BSD和Mac OS系統中比較有名的是kqueue,它可以高效地實時跟蹤Linux檔案系統的變化。近些年來,以fsnotify作為後端,幾乎所有的主流Linux發行版都支援Inotify機制。如何知道你的Linux核心是否支援Inotify機制呢?很簡單,執行下面這條命令:

% grep INOTIFY_USER /boot/config-$(uname -r)
CONFIG_INOTIFY_USER=y

如果輸出('CONFIG_INOTIFY_USER=y'),那麼你可以馬上享受Inotify之旅了。

簡單的檔案變化通知樣例:

好的開始是成功的一半,對於瞭解Inotify機制來說,讓我們從使用inotifywait程式開始,它包含在inotify-tools工具包中。假如我們打算監控/srv/test資料夾上的操作,只需執行:

% inotifywait -rme modify,attrib,move,close_write,create,delete,delete_self /srv/test
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

上述任務執行的同時,我們在另一個shell裡依次執行以下操作:建立資料夾,然後在新資料夾下建立檔案,接著刪除新建立的檔案:

% mkdir /srv/test/infoq
% echo TODO > /srv/test/infoq/article.txt
% rm /srv/test/infoq/article.txt

在執行inotifywait的shell中將會列印以下資訊:

/srv/test/ CREATE,ISDIR infoq
/srv/test/infoq/ CREATE article.txt
/srv/test/infoq/ MODIFY article.txt
/srv/test/infoq/ CLOSE_WRITE,CLOSE article.txt
/srv/test/infoq/ DELETE article.txt

顯而易見,只要有變化我們就會收到相關的通知。如果想了解關於Inotify提供的事件(如modify, atrrib等)的詳細資訊,請參考inotifywatch的manpage。實際使用時,如果並不想監控某個大資料夾,那麼就可以使用inotifywait的exclude選項。例如:我們要忽略資料夾/srv/test/large,那麼就可以這樣來建立監控:

% inotifywait --exclude '^/srv/test/(large|ignore)/' -rme modify,attrib,move,close_write,create,delete,delete_self /srv/test
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

上面的例子中,在exclude選項的匹配串中我們使用了正則表示式,因為我們不想將名稱中含有large或ignore的檔案也排除掉。我們可以測試一下:

% echo test > /srv/test/action.txt
% echo test > /srv/test/large/no_action.txt
% echo test > /srv/test/ignore/no_action.txt
% echo test > /srv/test/large-name-but-action.txt

這裡inotifywait應該只會報告'action.txt'和'large-name-but-action.txt'兩個檔案的變化,而忽略子資料夾'large'和'ignore'下的檔案,結果也確實如此;

/srv/test/ CREATE action.txt
/srv/test/ MODIFY action.txt
/srv/test/ CLOSE_WRITE,CLOSE action.txt
/srv/test/ CREATE large-name-but-action.txt
/srv/test/ MODIFY large-name-but-action.txt
/srv/test/ CLOSE_WRITE,CLOSE large-name-but-action.txt

另外,通過使用-t選項我們還可以定義inotifywait的監控時間,既可以讓它執行一段時間,也可以讓它一直執行。util-linux-ng的logger命令也可以實現此功能,不過得先把相關的訊息事件傳送到syslog,然後從syslog伺服器再分析整合。

Inotifywatch - 使用inotify來統計檔案系統訪問資訊

Inotify-tools中還有一個工具叫inotifywatch,它會先監聽檔案系統的訊息事件,然後統計每個被監聽檔案或資料夾的訊息事件,之後輸出統計資訊。比如我們想知道某個資料夾上有那些操作:

% inotifywatch -v -e access -e modify -t 120 -r ~/InfoQ
Establishing watches...
Setting up watch(es) on /home/mika/InfoQ
OK, /home/mika/InfoQ is now being watched.
Total of 58 watches.
Finished establishing watches, now collecting statistics.
Will listen for events for 120 seconds.
total  modify  filename
2      2       /home/mika/InfoQ/inotify/

很顯然,這裡我們監控的是~/InfoQ資料夾,並且可以看到/home/mika/InfoQ/inotify上發生了兩個事件。方法雖簡單,但卻很有效。

Inotify的配置選項

使用Inotify時,要特別注意核心中關於它的兩個配置。首先/proc/sys/fs/inotify/max_user_instances 規定了每個使用者所能建立的Inotify例項的上限;其次/proc/sys/fs/inotify/max_user_watches規定了每個Inotify例項最多能關聯幾個監控(watch)。你可以很容易地試驗在執行過程中達到上限,如:

% inotifywait -r /
Setting up watches.  Beware: since -r was given, this may take a while!
Failed to watch /; upper limit on inotify watches reached!
Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'.

如果要改變這些配置,只要向相應的檔案寫入新值即可,如下所示:

# cat /proc/sys/fs/inotify/max_user_watches
8192
# echo 16000 > /proc/sys/fs/inotify/max_user_watches
# cat /proc/sys/fs/inotify/max_user_watches
16000

使用Inotify的一些工具

近一段時間出現了很多基於Inotify的超炫的工具,如incron,它是一個類似於cron的守護程序(daemon),傳統的cron守護程序都是在規定的某個時間段內執行,而incron由於使用了Inotify,可以由事件觸發執行。同時incron的安裝簡單而直觀,比如在debian上,首先在/etc/incron.allow中新增使用incron的使用者(debian預設不允許使用者使用incron,因為如果incron使用不慎的話,例如形成死迴圈,則會導致系統宕機): 

# echo username > /etc/incron.allow

然後呼叫”incrontab -e“, 在彈出的編輯器中插入我們自己的規則,例如下面的這條簡單的規則,檔案一變化incron就會發郵件通知我們:

/srv/test/ IN_CLOSE_WRITE mail -s "[email protected]/$#\n" root

從現在開始,一旦/src/test資料夾中的檔案被修改,就會發送一封郵件。但是注意不要讓incron監控整個子目錄樹,因為Inotify只關注inodes,而不在乎是檔案還是資料夾,所以基於Inotify的軟體都需要自己來處理/預防遞迴問題。關於incontab詳細使用,請參考incrontab的manpage。

如果你還要處理incoming資料夾,那麼你可能需要inoticoming。當有檔案進入incoming資料夾時Inoticoming就會執行某些動作,從而可以用inoticoming來管理debian的軟體倉庫(例如軟體倉庫中一旦有上傳原始碼包或是新新增的二進位制包就立刻自動進行編譯),另外,還可以用它來監控系統是否有新上傳檔案,如果有就傳送通知。類似的工具還有(它們都各有專長):inosync(基於訊息通知機制的資料夾同步服務),iwatch(基於Inotify的程式,對檔案系統進行實時監控),以及lsyncd(一個守護程序(daemon),使用rsync同步本地資料夾)。

Inotify甚至對傳統的Unix工具也進行了改進,例如tail。使用inotail,同時加上-f選項,就可以取代每秒輪詢檔案的做法。此外,GNU 的coreutils從版本7.5開始也支援Inotify了,我們可以執行下面的命令來確認:

# strace -e inotify_init,inotify_add_watch tail -f ~log/syslog
[...]
inotify_init()                          = 4
inotify_add_watch(4, "/var/log/syslog", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1

從現在開始,通過輪詢來確實檔案是否需要重新讀取的方法應該作為古董了。

在指令碼中使用Inotify

總結

綜上所述,Inotify為Linux提供了一套高效監控和跟蹤檔案變化的機制,它可以實時地處理、除錯以及監控檔案變化,而輪詢是一種延遲機制。對於系統管理員,關於實現事件驅動的服務如系統備份,構建服務以及基於檔案操作的程式除錯等,Inotify無疑提供了強大的支援。

感謝侯伯薇對本文的審校。

給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至[email protected]。也歡迎大家加入到InfoQ中文站使用者討論組中與我們的編輯和其他讀者朋友交流。

Android檔案監控FileObserver介紹

在前面介紹了Linux對檔案變更監控過程。Android系統在此基礎上封裝了一個FileObserver類來方便使用Inotify機制。FileObserver是一個抽象類,需要定義子類實現該類的onEvent抽象方法,當被監控的檔案或者目錄發生變更事件時,將回調FileObserver的onEvent()函式來處理檔案或目錄的變更事件。

事件監控過程

在FileObserver類中定義了一個靜態內部類ObserverThread,該執行緒類才是真正實現檔案或目錄監控過程。各種型別的FileObserver都擁有一個ObserverThread例項:

frameworks\base\core\java\android\os\FileObserver.java

01.public abstract class FileObserver { 02.//可監控的事件型別 03.public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE 04.| CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE | DELETE_SELF | MOVE_SELF; 05.//靜態建立並啟動一個檔案監控執行緒 06.private static ObserverThread s_observerThread; 07.static { 08.s_observerThread = new ObserverThread(); 09.s_observerThread.start(); 10.} 11.// instance 12.private String m_path; 13.private Integer m_descriptor; 14.private int m_mask; 15.}

FileObserver類通過靜態方式構造了一個ObserverThread物件:

1.public ObserverThread() { 2.super("FileObserver"); 3.m_fd = init();//初始化一個inotify例項,Observer執行緒就是對該inotify例項進行監控 4.}

frameworks\base\core\jni\android_util_FileObserver.cpp

1.static jint android_os_fileobserver_init(JNIEnv* env, jobject object) 2.{ 3.#ifdef HAVE_INOTIFY 4.return (jint)inotify_init();//初始化一個inotify例項   5.

相關推薦

InotifyAndroid檔案監控FileObserver原理

概要 - 為什麼需要監控檔案系統? 在日常工作中,人們往往需要知道在某些檔案(夾)上都有那些變化,比如: 通知配置檔案的改變 跟蹤某些關鍵的系統檔案的變化 監控某個分割槽磁碟的整體使用情況 系統崩潰時進行自動清理 自動觸發備份程序 向伺服器上傳檔案結束時發出通知 通常使

Android效能監控實現原理

涉及知識點:APM, java Agent, plugin, bytecode, asm, InvocationHandler, smail 一. 背景介紹 APM : 應用程式效能管理。 2011年時國外的APM行業 NewRelic 和 APPDynamics 已經在該

iOS中xibstoryboard原理Android界面布局的異同

ast int mvc color ron rect sdn -m control 用文本標記語言來進行布局,用的最多的應該是HTML語言。HTML能夠理解為有一組特殊標記的XML語言。 一、iOS中xib與storyboard顯示原理 在iOS中基

【Zabbix】SNMPtrap實現主動監控原理安裝配置

工欲善其事,必先利其器。作為一款強大的開源軟體,Zabbix號稱“Monitor Everything”,其所依賴的,很大程度上便是SNMP的資料採集支援。SNMP 協議是用來管理裝置的協議,目前SNMP已成為網路管理領域中事實上的工業標準,並被廣泛支援和應用,大多數網路管理系統和平臺都是基於SNMP的。如果

【Zabbix】SNMPtrap-實現主動監控原理安裝配置

工欲善其事,必先利其器。作為一款強大的開源軟體,Zabbix號稱“Monitor Everything”,其所依賴的,很大程度上便是SNMP的資料採集支援。SNMP 協議是用來管理裝置的協議,目前SNMP已成為網路管理領域中事實上的工業標準,並被廣泛支援和應用,大多數網路管理系統和平臺都是基於SNM

android程序間傳遞檔案描述符原理

在linux中,程序開啟一個檔案,返回一個整數的檔案描述符,然後就可以在這個檔案描述符上對該檔案進行操作。那麼檔案描述符和檔案到底是什麼關係?程序使用的是虛擬地址,不同程序間是地址隔離的,如何在兩個程序中傳遞檔案描述符,然後指向同一檔案(binder傳遞檔案描述符)? li

JAVAEE——SpringBoot配置:配置檔案、YAML語法、檔案值注入、載入位置順序、自動配置原理

# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAu

重定向檔案,具體原理

文章目錄 重定向與檔案具體原理(對具體實現中的知識點說明) 1.單字元I/O:getchar()和putchar() 2.結束鍵盤輸入 3.0 重定向與檔案 3.1 重定向輸入 3.2 重定向輸出

android 檔案許可權的含義,修改檔案許可權

Android 檔案的許可權的含義: 檔案許可權一共有十個字元: 第一個字元代表檔案的型別: 當為[ d ]則是目錄,例如上表檔名為『.gconf』的那一行; 當為[ - ]則是檔案,例如上表檔名為『install.log』那一行; 若是[ l ]則表示為連

Huffman樹檔案壓縮的原理

1、Huffman樹的簡單介紹以及帶權路徑長度的求解        Huffman樹,又稱為最優二叉樹,是加權路徑長度(weighted path length)最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的葉結點的權值乘上其到根結點的路徑長度。    

Android 效能監控分析方法

Android應用效能測試通常包括:啟動時間、記憶體、CPU、耗電量、流量、流暢度等。 top 命令檢視CPU佔用率 top命令使用 Usage: top [ -m max_procs ] [ -n iterations ] [ -

什麼是分散式檔案系統?分散式檔案系統的原理、出現的問題解決方法

本地檔案系統如ext3,reiserfs等(這裡不討論基於記憶體的檔案系統),它們管理本地的磁碟儲存資源、提供檔案到儲存位置的對映,並抽象出一套檔案訪問介面供使用者使用。但隨著網際網路企業的高速發展,這些企業對資料儲存的要求越來越高,而且模式各異,如淘寶主站的大量商品圖片,其

Android 效能監控系列一(原理篇)

歡迎關注微信公眾號:BaronTalk,獲取更多精彩好文! 一. 前言 效能問題是導致 App 使用者流失的罪魁禍首之一,如果使用者在使用我們 App 的時候遇到諸如頁面卡頓、響應速度慢、發熱嚴重、流量電量消耗大等問題的時候,很可能就會解除安

Android中的ClassLoaderdex檔案加密實現分析

Android中的ClassLoader BaseDexClassLoader Dex類載入器的基類,包含Dex類載入器之間通用功能的實現。 DexClassLoader A class loader that loads classes from .jar

Android的控制元件架構自定義控制元件原理

android控制元件架構 Android中的每個控制元件都會在介面上得到一塊矩形的區域,而在Android中,控制元件大致被分為兩類,即ViewGroup 控制元件和View控制元件。ViewGroup控制元件作為父控制元件可以包含多個View控制元件,並管

Android Wi-Fi P2P原理原始碼學習

一,Wi-Fi P2P相關知識 (一)P2P及其依賴的技術項 (二)P2P工作流程 包括1.裝置的發現、2.組協調、3.認證關聯、4.WPS以及4次握手。總體流程如下圖:   1.  Device

UnityAndroid——Androidmanifest.xml檔案的介紹

說明: 在Unity開發移動平臺相關應用程式時,難免會涉及到一些必要的外掛(如:社會化分享外掛ShareSDK、Umeng;增強現實開發Vufoia;掃描二維碼外掛等一些列),每一種外掛分開使用時特別好用,無需特殊配置,使用Example案例就能快速上手使用。然後,當有時同

Android下載檔案實際檔案大小不一致,開啟失敗

問題的解決辦法是:檔案請求地址的中文 檔名需要進行轉碼 UploadFile/從保護模式到段_20140103101409.pdf UploadFile/%E4%BB%8E%E4%BF%9D%E6%8A%A4%E6%A8%A1%E5%BC%8F%E5%88%B0%E6%

分散式檔案系統:原理、問題方法

本地檔案系統如ext3,reiserfs等(這裡不討論基於記憶體的檔案系統),它們管理本地的磁碟儲存資源、提供檔案到儲存位置的對映,並抽象出一套檔案訪問介面供使用者使用。但隨著網際網路企業的高速發展,這些企業對資料儲存的要求越來越高,而且模式各異,如淘寶主站的大量商品圖片,

inotify檔案監控

轉自http://blog.csdn.NET/hjhcs121/article/details/7477147 inotify是什麼?用它能幹些什麼?          通俗點說它是一個核心用於通知使用者空間程式檔案系統變化的系統,並且它是powerful yet simple的。 inotif