lamant 发表于 2014-5-30 13:54:51

实时监控指定目录的txt文件,求指导!

目的:实时监控指定目录的txt文本文件的变化。
原本的想法,是每隔一段时间,读取txt文本文件的内容,跟前一次对比。这种做法太耗资源。
现在发现有API函数FindFirstChangeNotification、FindNextChangeNotification可以实现,这两个API函数包含在kernel32.dll中。一旦发现指定目录下的TXT文件修改时间有变化(FILE_NOTIFY_CHANGE_LAST_WRITE),就去读出最后一行【Readline(-1)】。然后开始监控下一次(FindNextChangeNotification)。
苦逼的LZ不会用dllcall,请帮忙看看,代码怎么写好呢。感谢您的帮助!{:face (411):}


函数原型如下:
HANDLE FindFirstChangeNotification(
LPCTSTR lpPathName, // 指定要监视的目录
BOOL bWatchSubtree, // 指定是否监视lpPathName 目录下的所有子目录
DWORD dwNotifyFilter // 指定过滤条件
dwNotifyFilter 参数指定了能够满足改变通知等待(即能够使等待函数返回)的过滤条件,
可以是以下值的组合:
FILE_NOTIFY_CHANGE_FILE_NAME 要求监视文件名称的改变
FILE_NOTIFY_CHANGE_DIR_NAME 要求监视目录名称的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES 要求监视属性的改变
FILE_NOTIFY_CHANGE_SIZE 要求监视文件大小的改变
FILE_NOTIFY_CHANGE_LAST_WRITE 要求监视最后写入时间的改变
FILE_NOTIFY_CHANGE_SECURITY 要求监视安全属性的改变
函数执行成功返回值是改变通知对象句柄,INVALID_HANDLE_VALUE 是失败后的返回值。返回的句柄可传递给等待函数(如WaitForSingleObject 等)。当监视的目录或子目录中一个过滤条件满足的时候,等待就会返回。
等待函数返回之后,应用程序可以处理这个改变,并调用FindNextChangeNotification 函数继续监视目录。当不再使用这个句柄时,应当调用FindCloseChangeNotification 函数关闭它。

shqf 发表于 2014-5-30 16:36:47

DLLCALL难啊,不过内部函数也可达到你的要求啊:
FileGetTime获取文件修改时间,_FileCountLines获取文件总行数,FileReadLine读取指定行内容。

lamant 发表于 2014-5-30 17:25:30

回复 2# shqf

谢谢shqf兄。
FileGetTime这个内部函数不知道是不是调用的API函数实现的(FindFirstChangeNotification?),我查查。

joyran 发表于 2014-5-30 22:42:51

都研究到这程度了,厉害

gto250 发表于 2014-5-31 00:21:45

帮助里有现成的

#include <WinAPIFiles.au3>
#include <APIFilesConstants.au3>
#include <WinAPI.au3>
#include <MsgBoxConstants.au3>

Opt('TrayAutoPause', 0)

Global Const $sPath = @ScriptDir & '\~TEST~'

DirCreate($sPath)
If Not FileExists($sPath) Then
    MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to create folder.')
    Exit
EndIf

OnAutoItExitRegister('OnAutoItExit')

Global $hObj
$hObj = _WinAPI_FindFirstChangeNotification($sPath, $FILE_NOTIFY_CHANGE_FILE_NAME)
$hObj = _WinAPI_FindFirstChangeNotification($sPath, $FILE_NOTIFY_CHANGE_LAST_WRITE)

If (Not $hObj) Or (Not $hObj) Then
    MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to create change notification.')
    Exit
EndIf

Local $tObj = DllStructCreate('ptr;ptr')
Local $pObj = DllStructGetPtr($tObj)
For $i = 0 To 1
    DllStructSetData($tObj, $i + 1, $hObj[$i])
Next

Local $ID
While 1
    Sleep(100)
    $ID = _WinAPI_WaitForMultipleObjects(2, $pObj, 0, 0)
    Switch $ID
      Case 0 ; WAIT_OBJECT_0
            ConsoleWrite('A file was created, renamed, or deleted in the directory.' & @CRLF)
      Case 1 ; WAIT_OBJECT_0 + 1
            ConsoleWrite('A file changed.' & @CRLF)
      Case Else
            ContinueLoop
    EndSwitch
    If Not _WinAPI_FindNextChangeNotification($hObj[$ID]) Then
      MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unexpected error.')
      Exit
    EndIf
WEnd

Func OnAutoItExit()
    For $i = 0 To 1
      If $hObj[$i] Then
            _WinAPI_FindCloseChangeNotification($hObj[$i])
      EndIf
    Next
    DirRemove($sPath, 1)
EndFunc   ;==>OnAutoItExit

lamant 发表于 2014-6-3 08:45:30

回复 4# joyran

⊙﹏⊙b汗,不像您说的这样,哈哈。
我只是想用autoit来实现实时监控TXT文件的变化,一直搜索,就了解到这个API函数了。

lamant 发表于 2014-6-3 08:46:10

回复 5# gto250


    谢谢gto250大神的帮助!
页: [1]
查看完整版本: 实时监控指定目录的txt文件,求指导!