Window Linux下實現指定目錄內文件變更的監控方法

轉自:http://qbaok.blog.163.com/blog/static/10129265201112302014782/

對于監控指定目錄內文件變更,window 系統提供了兩個未公開API:SHChangeNotifyRegister? SHChangeNotifyDeregister 分別用于注冊Notify以及監視。

同時,還提供了ReadDirectoryChangesW? 函數(貌似NT以上可用)。

在 .net framework 中,另提供了封裝好的 FileSystemWatcher 來實現此功能。

至于 JAVA PHP 神馬的,太晚了,懶得查了,以后再說。

============ 【分割線】=============

ReadDirectoryChangesW 函數具體信息如下:

對指定的目錄進行監控,返回詳細的文件變化信息。

函數形式

01 BOOL WINAPI ReadDirectoryChangesW(

02 __in???????? HANDLE hDirectory,?? // 對目錄進行監視的句柄

03 __out??????? LPVOID lpBuffer,???? // 一個指向DWORD類型的緩沖區,其中可以將獲取的數據結果將其返回。

04 __in???????? DWORD nBufferLength, // 指lpBuffer的緩沖區的大小值,以字節為單位。

05 __in???????? BOOL bWatchSubtree, // 監視目錄. 一般選擇 TRUE

06 __in???????? DWORD dwNotifyFilter, // 對文件過濾的方式和標準

07 __out_opt??? LPDWORD lpBytesReturned, // 將接收的字節數轉入lpBuffer參數

08 __inout_opt LPOVERLAPPED lpOverlapped, // 一般選擇 NULL

09 __in_opt???? LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // 一般選擇 NULL

10 );

1.hDirectory [中]

?????? This directory must be opened with the FILE_LIST_DIRECTORY access right.

?????? 被監視的目錄必須打開FILE_LIST_DIRECTORY的訪問權限

2.lpBuffer[中]

?????? The structure of this buffer is defined by the FILE_NOTIFY_INFORMATION structure

?????? 這個緩沖區的定義是FILE_NOTIFY_INFORMATION結構。

?????? This buffer is filled either synchronously or asynchronously,

?????? depending on how the directory is opened and what value is given to the lpOverlapped parameter.

?????? 這個緩沖區充滿要么同步或異步,這取決于如何打開目錄什么價值給予lpOverlapped參數。

3.nBufferLength [中]

?????? The size of the buffer that is pointed to by the lpBuffer parameter, in bytes.

?????? 大小的緩沖區,是指出的lpBuffer參數,以字節為單位。

4.bWatchSubtree [中]

?????? If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory.

?????? 如果這個參數是TRUE,那么這個函數會監視目錄樹,所指定的當前的根目錄(整個路徑信息都顯示出來)。

?????? If this parameter is FALSE, the function monitors only the directory specified by the hDirectory parameter.

?????? 如果這個參數是FALSE ,則函數則只監視hDirectory句柄所指定的目錄下的內容(只顯示出發生變化的文件目錄)。

5.dwNotifyFilter [中]

?????? The filter criteria that the function checks to determine if the wait operation has completed.

?????? 該過濾器的標準,功能檢查,以決定是否等待操作完成。

?????? This parameter can be one or more of the following values.這個參數可以是一個或多個下列值。

????? 【FILE_NOTIFY_CHANGE_FILE_NAME】 0x00000001

?????? Any file name change in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何文件名改變 都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

?????? Changes include renaming, creating, or deleting a file.

?????? 變化包括重命名,創建或刪除文件。

????? 【FILE_NOTIFY_CHANGE_DIR_NAME】 0x00000002

?????? Any directory-name change in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何目錄名稱改變 都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

?????? Changes include creating or deleting a directory.

?????? 改變包括建立或刪除一個目錄。

????? 【FILE_NOTIFY_CHANGE_ATTRIBUTES】 0x00000004

?????? Any attribute change in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何屬性變化,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

????? 【FILE_NOTIFY_CHANGE_SIZE】 0x00000008

?????? Any file-size change in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何文件大小的變化,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

?????? The operating system detects a change in file size only when the file is written to the disk.

?????? 操作系統檢測改變文件大小,只有當該文件被寫入到磁盤時發生。

?????? For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

?????? 操作系統使用廣泛緩存,檢測時才會發生的緩存足夠同滿。

????? 【FILE_NOTIFY_CHANGE_LAST_WRITE】0x00000010

?????? Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何改變過去修改時間的文件 ,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

?????? The operating system detects a change to the last write-time only when the file is written to the disk.

?????? 操作系統檢測改變過去寫的時間只有當該文件被寫入到磁盤。

?????? For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

?????? 操作系統使用廣泛緩存,檢測時才會發生的緩存足夠同滿。

????? 【FILE_NOTIFY_CHANGE_LAST_ACCESS】0x00000020

?????? Any change to the last access time of files in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何改變文件最近訪問時間,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

????? 【FILE_NOTIFY_CHANGE_CREATION】 0x00000040

?????? Any change to the creation time of files in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何改變文件的創建時間的,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

????? 【FILE_NOTIFY_CHANGE_SECURITY】0x00000100

?????? Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.

?????? 任何安全描述符被改變的,都會查看所在目錄或子目錄的變更,并將結果通知給等待操作返回。

6.lpBytesReturned [了,可選]

?????? For synchronous calls, this parameter receives the number of bytes transferred into the lpBuffer parameter.

?????? 同步調用,這個參數接收的字節數轉入lpBuffer參數。

?????? For asynchronous calls, this parameter is undefined.

?????? 異步調用,這個參數是未定義的。

?????? You must use an asynchronous notification technique to retrieve the number of bytes transferred.

?????? 您必須使用異步通知技術檢索的字節數轉移。

7.lpOverlapped [中,那樣,可選]

?????? A pointer to an OVERLAPPED structure that supplies data to be used during asynchronous operation.

?????? 一個指針的重疊結構,提供供數據時使用的異步操作。

?????? Otherwise, this value is NULL.

?????? 否則,這個值為NULL 。

?????? The Offset and OffsetHigh members of this structure are not used.

?????? OFFSET和OffsetHigh成員結構不使用。

8.lpCompletionRoutine [中,可選]

?????? A pointer to a completion routine to be called when the operation has been completed or canceled and the calling

?????? thread is in an alertable wait state.

?????? 一個指針一個完成例程 如果在呼叫使用函數操作時已經完成或取消和調用線程是在alertable等待狀態。

返回值

?????? If the function succeeds, the return value is nonzero.

?????? 如果函數成功,返回值為非零。

?????? For synchronous calls, this means that the operation succeeded.

?????? 同步要求,這意味著操作取得了成功。

?????? For asynchronous calls, this indicates that the operation was successfully queued.

?????? 異步調用,這表明操作成功排隊。

If the function fails, the return value is zero.

如果函數失敗,返回值是零。

To get extended error information, call GetLastError .

要獲得擴展錯誤信息,請用GetLastError返回錯誤 。

If the network redirector or the target file system does not support this operation, the function fails with ERROR_INVALID_FUNCTION.

如果網絡重定向或目標文件系統不支持這一行動,該功能失敗, ERROR_INVALID_FUNCTION 。

========= 抄來的 delphi FileSystemWatcher 實現 ==========

{*******************************************************}

{?????????????????????????????????????????????????????? }

{?????? FileSystemWatcher?????????????????????????????? }

{?????????????????????????????????????????????????????? }

{?????? 版權所有 (C) 2007 solokey?????????????????????? }

{?????????????????????????????????????????????????????? }

{?????? http://blog.csdn.net/solokey??????????????????? }

{?????????????????????????????????????????????????????? }

{*******************************************************}

unit FileSystemWatcher;

interface

uses

? Windows, Classes, SysUtils;

type

? TFileOperation = (foAdded, foRemoved, foModified, foRenamed);

? TFileDealMethod = procedure(FileOperation: TFileOperation; const FileName1,FileName2: string) of object;

? TNotifyFilter = (nfFileNameChange, nfDirNameChange, nfAttributeChange,

??? nfSizeChange, nfWriteChange, nfAccessChange, nfCreationDateChange, nfSecurityChange);

? TNotifyFilters = set of TNotifyFilter;

? TNotificationBuffer =? array[0..4095] of Byte;

? PFileNotifyInformation = ^TFileNotifyInformation;

? TFileNotifyInformation = record

??? NextEntryOffset: DWORD;

??? Action: DWORD;

??? FileNameLength: DWORD;

??? FileName: array[0..0] of WideChar;

? end;

? TShellChangeThread = class(TThread)

? private

??? FActived: Boolean;

??? FDirectoryHandle: Cardinal;

??? FCS: TRTLCriticalSection;

??? FChangeEvent: TFileDealMethod;

??? FDirectory: string;

??? FWatchSubTree: Boolean;

??? FCompletionPort: Cardinal;

??? FOverlapped: TOverlapped;

??? FNotifyOptionFlags: DWORD;

??? FBytesWritten: DWORD;

??? FNotificationBuffer: TNotificationBuffer;

? protected

??? procedure Execute; override;

??? procedure DoIOCompletionEvent;

??? function ResetReadDirctory: Boolean;

??? procedure Lock;

??? procedure Unlock;

? public

??? constructor Create(ChangeEvent: TFileDealMethod); virtual;

??? destructor Destroy; override;

??? procedure SetDirectoryOptions(Directory : String; Actived: Boolean; WatchSubTree : Boolean;

????? NotifyOptionFlags : DWORD);

??? property ChangeEvent : TFileDealMethod read FChangeEvent write FChangeEvent;

? end;

? TFileSystemWatcher = class(TComponent)

? private

??? FActived: Boolean;

??? FWatchedDir: string;

??? FThread: TShellChangeThread;

??? FOnChange: TFileDealMethod;

??? FWatchSubTree: Boolean;

??? FFilters: TNotifyFilters;

??? procedure SetWatchedDir(const Value: string);

??? procedure SetWatchSubTree(const Value: Boolean);

??? procedure SetOnChange(const Value: TFileDealMethod);

??? procedure SetFilters(const Value: TNotifyFilters);

??? function? NotifyOptionFlags: DWORD;

??? procedure SetActived(const Value: Boolean);

? protected

??? procedure Change;

??? procedure Start;

??? procedure Stop;

? public

??? constructor Create(AOwner : TComponent); override;

??? destructor? Destroy; override;

? published

??? property? Actived:Boolean? read FActived write SetActived;

??? property? WatchedDir: string read FWatchedDir write SetWatchedDir;

??? property? WatchSubTree: Boolean read FWatchSubTree write SetWatchSubTree;

??? property? NotifyFilters: TNotifyFilters read FFilters write SetFilters;

??? property? OnChange: TFileDealMethod read FOnChange write SetOnChange;

? end;

procedure? Register;

implementation

procedure? Register;

begin

? RegisterComponents('Samples', [TFileSystemWatcher]);

end;

{ TShellChangeThread }

constructor TShellChangeThread.Create(ChangeEvent: TFileDealMethod);

begin

? FreeOnTerminate := True;

? FChangeEvent := ChangeEvent;

? InitializeCriticalSection(FCS);

? FDirectoryHandle := 0;

? FCompletionPort := 0;

? inherited Create(True);

end;

destructor TShellChangeThread.Destroy;

begin

? CloseHandle(FDirectoryHandle);

? CloseHandle(FCompletionPort);

? DeleteCriticalSection(FCS);

? inherited Destroy;

end;

procedure TShellChangeThread.DoIOCompletionEvent;

var

? TempBuffer: TNotificationBuffer;

? FileOpNotification: PFileNotifyInformation;

? Offset: Longint;

? FileName1, FileName2: string;

? FileOperation: TFileOperation;

? procedure DoDirChangeEvent;

? begin

??? if Assigned(ChangeEvent) and FActived then

????? ChangeEvent(FileOperation, FileName1, FileName2);

? end;

? function? CompleteFileName(const FileName:string):string;

? begin

??? Result := '';

??? if Trim(FileName) <> '' then

????? Result := FDirectory + Trim(FileName);

? end;

begin

? Lock;

? TempBuffer := FNotificationBuffer;

? FillChar(FNotificationBuffer, SizeOf(FNotificationBuffer), 0);

? Unlock;

? Pointer(FileOpNotification) := @TempBuffer[0];

? repeat

??? with FileOpNotification^ do begin

????? Offset := NextEntryOffset;

????? FileName2 := '';

????? case Action of

??????? FILE_ACTION_ADDED..FILE_ACTION_MODIFIED: begin

????????? FileName1 := CompleteFileName(WideCharToString(FileName));

????????? FileOperation := TFileOperation(Action - 1);

????????? DoDirChangeEvent;

??????? end;

??????? FILE_ACTION_RENAMED_OLD_NAME: begin

????????? FileName1 := CompleteFileName(WideCharToString(FileName));

????????? FileOperation := TFileOperation(Action - 1);

??????? end;

??????? FILE_ACTION_RENAMED_NEW_NAME: begin

????????? if FileOperation = foRenamed then begin

??????????? FileName2 := CompleteFileName(WideCharToString(FileName));

??????????? DoDirChangeEvent;

????????? end;

??????? end;

????? end;

??? end;

? Pointer(FileOpNotification) := Pointer(PChar(FileOpNotification) + OffSet);

? until Offset=0;

end;

procedure TShellChangeThread.Execute;

var

? numBytes: DWORD;

? CompletionKey: DWORD;

? PFOverlapped: POverlapped;

? TempDirectoryHandle: Cardinal;

? TempCompletionPort: Cardinal;

begin

? while not Terminated do begin

??? Lock;

??? TempDirectoryHandle := FDirectoryHandle;

??? TempCompletionPort := FCompletionPort;

??? Unlock;

??? if TempDirectoryHandle > 0? then begin

????? PFOverlapped := @FOverlapped;

????? GetQueuedCompletionStatus(TempCompletionPort, numBytes, CompletionKey, PFOverlapped, INFINITE);

????? if CompletionKey = Handle then begin

??????? Synchronize(DoIOCompletionEvent);

??????? FBytesWritten := 0;

??????? FillChar(FNotificationBuffer, SizeOf(FNotificationBuffer), 0);

??????? ReadDirectoryChanges(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer), FWatchSubTree, FNotifyOptionFlags, @FBytesWritten, @FOverlapped, nil);

????? end;

??? end;

? end;

? PostQueuedCompletionStatus(TempCompletionPort, 0, 0, nil);

end;

procedure TShellChangeThread.Lock;

begin

? EnterCriticalSection(FCS);

end;

function TShellChangeThread.ResetReadDirctory: Boolean;

var

? TempHandle: Cardinal;

? TempCompletionPort: Cardinal;

begin

? Result := False;

? CloseHandle(FDirectoryHandle);

? PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);

? CloseHandle(FCompletionPort);

? TempHandle := CreateFile(PChar(FDirectory), GENERIC_READ or GENERIC_WRITE,

??????????????????????????? FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,

??????????????????????????? nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);

? Lock;

? FDirectoryHandle := TempHandle;

? Unlock;

? if (GetLastError = ERROR_FILE_NOT_FOUND) or (GetLastError = ERROR_PATH_NOT_FOUND) then begin

??? Lock;

??? FDirectoryHandle := 0;

??? FCompletionPort := 0;

??? Unlock;

??? Exit;

? end;

? TempCompletionPort := CreateIoCompletionPort(FDirectoryHandle, 0, Handle, 0);

? Lock;

? FCompletionPort := TempCompletionPort;

? Unlock;

? FBytesWritten := 0;

? FillChar(FNotificationBuffer, SizeOf(FNotificationBuffer), 0);

? Result := ReadDirectoryChanges(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer), FWatchSubTree, FNotifyOptionFlags, @FBytesWritten, @FOverlapped, nil);

end;

procedure TShellChangeThread.SetDirectoryOptions(Directory: String; Actived: Boolean;

? WatchSubTree: Boolean;? NotifyOptionFlags : DWORD);

begin

? FWatchSubTree := WatchSubTree;

? FNotifyOptionFlags := NotifyOptionFlags;

? FDirectory := IncludeTrailingBackslash(Directory);

? FActived := Actived;

? ResetReadDirctory;

end;

procedure TShellChangeThread.Unlock;

begin

? LeaveCriticalSection(FCS);

end;

{ TFileSystemWatcher }

procedure TFileSystemWatcher.Change;

begin

? if csDesigning in ComponentState then

??? Exit;

? if Assigned(FThread) then begin

??? FThread.SetDirectoryOptions(FWatchedDir, FActived, LongBool(FWatchSubTree), NotifyOptionFlags);

? end;

end;

constructor TFileSystemWatcher.Create(AOwner: TComponent);

begin

? inherited Create(AOwner);

? FActived := False;

? FWatchedDir := 'C:\';

? FFilters := [nfFilenameChange, nfDirNameChange];

? FWatchSubTree := True;

? FOnChange := nil;

end;

destructor TFileSystemWatcher.Destroy;

begin

? if Assigned(FThread) then

??? FThread.Terminate;

? inherited Destroy;

end;

function TFileSystemWatcher.NotifyOptionFlags: DWORD;

begin

? Result := 0;

? if nfFileNameChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_FILE_NAME;

? if nfDirNameChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_DIR_NAME;

? if nfSizeChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_SIZE;

? if nfAttributeChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_ATTRIBUTES;

? if nfWriteChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_LAST_WRITE;

? if nfAccessChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_LAST_ACCESS;

? if nfCreationDateChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_CREATION;

? if nfSecurityChange in FFilters then

??? Result := Result or FILE_NOTIFY_CHANGE_SECURITY;

end;

procedure TFileSystemWatcher.SetActived(const Value: Boolean);

begin

? if FActived <> Value then begin

??? FActived := Value;

??? Change;

??? if FActived then

????? Start

??? else

????? Stop;

? end;

end;

procedure TFileSystemWatcher.SetFilters(const Value: TNotifyFilters);

begin

? if FFilters <> Value then begin

??? FFilters := Value;

??? Change;

? end;

end;

procedure TFileSystemWatcher.SetOnChange(const Value: TFileDealMethod);

begin

? FOnChange := Value;

? if Assigned(FOnChange) and FActived then

??? Start

? else

??? Stop;

? Change;

end;

procedure TFileSystemWatcher.SetWatchedDir(const Value: string);

begin

? if not SameText(FWatchedDir, Value) then begin

??? FWatchedDir := Value;

??? Change;

? end;

end;

procedure TFileSystemWatcher.SetWatchSubTree(const Value: Boolean);

begin

? if FWatchSubTree <> Value then begin

??? FWatchSubTree := Value;

??? Change;

? end;

end;

procedure TFileSystemWatcher.Start;

begin

? if csDesigning in ComponentState then

??? Exit;

? if Assigned(FOnChange) then begin

??? FThread := TShellChangeThread.Create(FOnChange);

??? FThread.SetDirectoryOptions(FWatchedDir, FActived, LongBool(FWatchSubTree), NotifyOptionFlags);

??? FThread.Resume;

? end;

end;

procedure TFileSystemWatcher.Stop;

begin

? if csDesigning in ComponentState then

??? Exit;

? if Assigned(FThread) then begin

??? FThread.Terminate;

??? FThread := nil;

? end;

end;

end.

============ 【分割線】=============

至于 Linux 么…… PW 哥給找的 Linux inotify 還是很給力的。

見 http://snipt.org/wngpo

  1. #!/bin/bash

  2. SRC=/home/pw/workspace/daobo/web_demo/

  3. DST=username@remote_host:/home/pw/workspace/resin-3.0.21/webapps/daobo-demo

  4. inotifywait -mrq -e modify --exclude=".*\.swp|\.svn|.*\~" $SRC |while read D E F;do

  5. rsync -avz $SRC $DST --exclude=".svn" --exclude=".*\.swp"

  6. done

至于這鳥玩意是個啥,怎么裝,資料如下:

inotify 是什么

Inotify一種強大的、細粒度的、異步文件系統監控機制,它滿足各種各樣的文件監控需要,可以監控文件系統的訪問屬性、讀寫屬性、權限屬性、刪除創建 移動等操作,也就是可以監控文件發生的一切變化,我們可以利用內核提供的這個屬性,在文件發生任何變化時都觸發rsync同步動作,這樣就做到數據的實時 同步了。

Inotify的監控功能是需要內核支持的,Linux從kernel 2.6.13開始,Inotify功能正式加入內核,在RHEL5版本已經完全支持。

為什么使用 inotify?

使用 inotify 取代 dnotify 的原因有很多。第一個原因是,dnotify 需要您為每個打算監控是否發生改變的目錄打開一個文件描述符。當同時監控多個目錄時,這會消耗大量的資源, 因為有可能達到每個進程的文件描述符限制。

除此之外,文件描述符會鎖定目錄,不允許卸載(unmount)支持的設備,這在存在可移動介質的 環境中會引發問題。在使用 inotify 時,如果正在監控被卸載的文件系統上的文件,那么監控會被自動移除并且您會接收到一個卸載事件。

dnotify 不如 inotify 的第二個原因是 dnotify 有點復雜。注意,使用 dnotify 基礎設施的簡單文件系統監控粒度只 停留于目錄級別。為了使用 dnotify 進行更細粒度的監控,應用程序編程 人員必須為每個受監控的目錄保留一個 stat 結構的緩存。該用戶空間的 stat 結構緩存需要用來明確確定當接收到通知信號時目錄發生了什么變化。當獲得通知信號時,生成 stat 結構列表并與最新的狀態相比較。顯而易見,這種技術是不理想的。

inotify 的另一個優點是它使用文件描述符作為基本接口,使應用程序開發者使用 select 和 poll 來監控設備。這允許有效的多路 I/O 和與 Glib 的 mainloop 的集成。相反,dnotify 所使用的信號常常使程序員頭疼并且感覺不太優雅。

inotify 通過提供一個更優雅的 API 解決了這些問題,該 API 使用最少的文件描述符,并確保更細粒度的監控。與 inotify 的通信是通過設備節點提供的。基 于以上原因,對于監控 Linux 2.6 平臺上的文件,inotify 是您最明智的選擇。

另外,要在shell下使用inotify提供的特性,還需要安裝 inotify-tools,我們依次介紹如下:

安裝inotify-tools

可以在? http://inotify-tools.sourceforge.net/ 下載到inotify-tools,接著編譯安裝:

[root@web253 ~]# tar zxvf inotify-tools-3.13.tar.gz

[root@web253 ~]# cd inotify-tools-3.13

[root@web253 inotify-tools-3.13]# ./configure

[root@web253 inotify-tools-3.13]#make

[root@web253 inotify-tools-3.13]#make install

完成后,在系統下執行man inotify 、 man inotifywait、man inotifywatch即可得到相應的幫助信息。表示安裝成功。

使用inotify功能

可以通過如下命令查看系統是否支持inotify

[root@web253 bin]# uname -a

Linux web253 2.6.18-8.el5 #1 SMP Fri Jan 26 14:15:21 EST 2007 i686 i686 i386 GNU/Linux

[root@web253 bin]# ll /proc/sys/fs/inotify

total 0

-rw-r--r-- 1 root root 0 Feb 21 01:15 max_queued_events

-rw-r--r-- 1 root root 0 Feb 21 01:15 max_user_instances

-rw-r--r-- 1 root root 0 Feb 21 01:15 max_user_watches

如果有輸出,表示系統已經內核已經支持inotify。

inotify 可以監視的文件系統事件包括:

IN_ACCESS, 即文件被訪問

IN_MODIFY, 文件被 write

IN_ATTRIB, 文件屬性被修改,如 chmod、chown、touch 等

IN_CLOSE_WRITE, 可寫文件被 close

IN_CLOSE_NOWRITE, 不可寫文件被 close

IN_OPEN, 文件被 open

IN_MOVED_FROM, 文件被移走,如 mv

IN_MOVED_TO, 文件被移來,如 mv、cp

IN_CREATE, 創建新文件

IN_DELETE, 文件被刪除,如 rm

IN_DELETE_SELF, 自刪除,即一個可執行文件在執行時刪除自己

IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動自己

IN_UNMOUNT,宿主文件系統被 umount

IN_CLOSE,文件被關閉,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)

IN_MOVE,文件被移動,等同于(IN_MOVED_FROM | IN_MOVED_TO)

注:上面所說的文件也包括 目錄。

inotifywait 僅執行阻塞,等待 inotify 事件。您可以監控任何一組文件和目錄,或監控整個目錄樹(目錄、 子目錄、子目錄的子目錄等等)。在 shell 腳本中使用 inotifywait。

inotifywatch 收集關于被監視的文件系統的統計數據,包括每個 inotify 事件發生多少次。

inotify的系統相關參數

/proc interfaces

?????? The following interfaces can be used to limit the amount of kernel memory consumed by inotify:

/proc/sys/fs/inotify/max_queued_events

?????? The value in this file is used when an application calls inotify_init(2) to set an upper? limit? on? the number? of? events? that? can be queued to the corresponding inotify instance.? Events in excess of this limit are dropped, but an IN_Q_OVERFLOW event is always generated.

/proc/sys/fs/inotify/max_user_instances

??????? This specifies an upper limit on the number of inotify instances that can be created per real user ID.

/proc/sys/fs/inotify/max_user_watches

??????? This specifies a limit on the number of watches that can be associated with each inotify instance.

inotifywait 相關的命令(更多,查看manpage):

inotifywait

This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees.

-m, --monitor

????????????? Instead? of? exiting? after receiving a single event, execute indefinitely.? The default behaviour is to exit after the first event occurs.

-r, --recursive

????????????? Watch all subdirectories of any directories passed as arguments.? Watches will be set up recursively? to an? unlimited? depth.?? Symbolic? links? are? not traversed.? Newly created subdirectories will also be watched.

-q, --quiet

????????????? If specified once, the program will be less verbose.? Specifically, it will not state when it? has? completed establishing all inotify watches.

-e <event>, --event <event>

????????????? Listen for specific event(s) only.? The events which can be listened for are listed in the? EVENTS? section.? This option can be specified more than once.? If omitted, all events are listened for. use“,”separate multi events。

轉載于:https://www.cnblogs.com/zhuqn/p/4125776.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375467.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375467.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375467.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Odoo9發行說明

2015年10月1日&#xff0c;期待已久的Odoo9正式發布。本文是Odoo9正式版發行說明&#xff0c;基于官網資料翻譯。 譯者: 蘇州-微塵原文地址&#xff1a;https://www.odoo.com/page/odoo-9-release-notes譯文地址&#xff1a;http://blog.csdn.net/wangnan537/article/details/4…

揭秘史上最完美一步到位的搭建Andoriod開發環境

Windows環境下Android開發環境搭建雖然不難而且網上資料眾多&#xff0c;但是眾多資料如出一折 忽略了很多細節&#xff0c;最終還是沒能達到滿意效果。 基本步驟如下&#xff1a;JDK安裝、環境變量配置、Eclipse下載、AndoriodSDK下載安裝、下載配置ADT但是到這里還不算完美搞…

基于OpenCv的人臉檢測、識別系統學習制作筆記之二

在網上找到了一個博客&#xff0c;里面有大量內容適合初學者接觸和了解人臉檢測的博文&#xff0c;正好符合我目前的學習方面&#xff0c;故將鏈接放上來&#xff0c;后續將分類原博客的博文并加上學習筆記。 傳送門&#xff1a; http://blog.sina.com.cn/s/articlelist_160256…

URL 化

URL化。編寫一種方法&#xff0c;將字符串中的空格全部替換為%20。假定該字符串尾部有足夠的空間存放新增字符&#xff0c;并且知道字符串的“真實”長度。&#xff08;注&#xff1a;用Java實現的話&#xff0c;請使用字符數組實現&#xff0c;以便直接在數組上操作。&#xf…

第一章 00 StringUtil.cpp和StringUtil.hh分析

1 /*2 * StringUtil.hh3 *4 * Copyright 2002, Log4cpp Project. All rights reserved.5 *6 * See the COPYING file for the terms of usage and distribution.7 */8 頭文件的說明&#xff0c;以及與版權相關的說明一般都會放置在文件的開始位置 9 #ifndef _LOG4CPP_STR…

【SQL】服務器環境下的SQL

一、大型數據庫的三層體系結構 web服務器&#xff1a;比如在淘寶頁面上&#xff0c;輸入“牛肉干”&#xff0c;就是web服務器來處理&#xff0c;提交給應用服務器。 應用服務器&#xff1a;在獲取到“牛肉干”這個請求后&#xff0c;應用服務器決定如何匯集結果&#xff0c;并…

【置頂】全局變量的好處與壞處

近日在做項目的過程中對plsql的使用非常多&#xff0c;主要是編寫存儲過程實現業務邏輯。但是在coding的過程中遇到非常奇怪的問題。 問題是&#xff1a;在package包頭中定義了一個變量&#xff0c;current_time : sysdate,然后在procedure使用這個定義的變量&#xff0c;直接i…

三個線程按順序輸出數字

當 n 3N 時&#xff0c;線程1輸出 當 n 3N 1 時&#xff0c;線程2輸出 當 n 3N 2 時&#xff0c;線程3輸出 最終的輸出為 0、1、2、3、4、5、6、7、8、10 #include <iostream> #include <thread> #include <mutex> #include <condition_variable&g…

TextView實現自動滾動滾動.

必須有要四個屬性: android:ellipsize"marquee"; android:focusable"true";android"focusableInTouchMode"true";android:singleLine"true"; <TextViewandroid:layout_width"fill_parent"android:layout_height&quo…

用最少數量的箭引爆氣球

在二維空間中有許多球形的氣球。對于每個氣球&#xff0c;提供的輸入是水平方向上&#xff0c;氣球直徑的開始和結束坐標。由于它是水平的&#xff0c;所以y坐標并不重要&#xff0c;因此只要知道開始和結束的x坐標就足夠了。開始坐標總是小于結束坐標。平面內最多存在104個氣球…

ExtJS中使用ztree 不顯示樹的解決辦法

最近部門同事碰到一個問題&#xff0c;將ztree嵌入在套了幾層Panel的面板中不會正常顯示&#xff0c;但是將上層面板換成window就能正常顯示&#xff0c;開始以為是所在的外部容器不管嵌套了幾層&#xff0c;但是必須最底層是window容器&#xff0c;但是測試后發現不是這樣的&a…

尋找小鎮的法官

在一個小鎮里&#xff0c;按從 1 到 N 標記了 N 個人。傳言稱&#xff0c;這些人中有一個是小鎮上的秘密法官。 如果小鎮的法官真的存在&#xff0c;那么&#xff1a; 小鎮的法官不相信任何人。 每個人&#xff08;除了小鎮法官外&#xff09;都信任小鎮的法官。 只有一個人同…

事務的隔離界別

事務的ACID特性&#xff1a; 1、Atomicity原子性 事務操作的不可分割性&#xff0c;要么全部執行&#xff0c;要么回滾。 2、Consistency一致性 數據庫在事務處理前后處于的一致性狀態。如銀行轉賬&#xff0c;兩個賬戶轉賬前的狀態和轉賬后的狀態必須一致。 3、Isolation隔離…

程序員福利各大平臺免費接口非常適用

電商接口 京東獲取單個商品價格接口: http://p.3.cn/prices/mgets?skuIdsJ_商品ID&type1 ps:商品ID這么獲取:http://item.jd.com/954086.html 物流接口 快遞接口: http://www.kuaidi100.com/query?type快遞公司代號&postid快遞單號 ps:快遞公司編碼:申通”shentong”…

WriteN, RTMP send error

WriteN, RTMP send error 32 (133 bytes) WriteN, RTMP send error 32 (49 bytes) WriteN, RTMP send error 9 (42 bytes)現象&#xff1a; 推流失敗&#xff0c;srs服務出錯。 原因 視頻流較慢&#xff0c;音頻流較快。 復現 視頻解碼得到幀數據&#xff0c;用異步接口處…

樣式公用代碼

/************** bug ************/.clearfix:after {content:""; display:block; height:0px; clear:both; overflow:hidden;}.clearfix {display:inline-block;}.clearfix {display:block;} /************** 公共用 ************/html {overflow:-moz-scrollbars-v…

即時聊天IM之二 openfire 整合現有系統用戶

合肥程序員群&#xff1a;49313181。 合肥實名程序員群&#xff1a;128131462 (不愿透露姓名和信息者勿加入) Q Q:408365330 E-Mail:egojitqq.com 綜述&#xff1a; 每天利用中午時間更新下這個知識點的的博客如果感興趣的覺得更新慢了也別介意&#xff08;其它時間還是…

cannot convert ‘_IO_FILE*’ to ‘const char*

錯誤代碼 #ifdef NDEBUG#define DBUG_PRINT(fmt, ...) #else#define DBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__) #endifBUG_PRINT(stderr, "decode %s does not support device type cuda.\n", dec->name);修改 BUG_PRINT("decode %s does not supp…

找出數組中前K大的值

將數組劃分為兩部分&#xff0c;前K項為前K大值的集合&#xff0c;無需有序。 while(true) {int flag nums[k];while(i < k && nums[i] > flag) {i;}while(j>k && nums[j] < flag) {j--;}if (i j || nums[i] nums[j]) {break;}int tmp nums[i]…

C#在ASP.NET4.5框架下的首次網頁應用

運行效果預覽: 先看實踐應用要求: 1&#xff0e;編寫一個函數&#xff0c;用于計算1&#xff01;2&#xff01;3&#xff01;4&#xff01;5&#xff01;&#xff0c;在控制臺或頁面輸出運行結果。 2&#xff0e;在控制臺或頁面輸出九九乘法表。 3&#xff0e;輸入10個以內的整…