我最近写了一个程序,是监控文件内容的改动(文件内容可能很多),在TForm中使用了TTimer和Tmemo组件,用TTimer组件是定时读取文件的内容;假如我的程序第一次启动,就会把文件的内容一次性读取,显示在TMemo中,当在一定时间里再次去读取文件,如果文件内容有增加,则将增加的内容加入到TMemo中(上次读取的内容不清除),这样就不用每次去将文件的内容全部取来显示;我的代码如下:procedure TForm1.Timer1Timer(Sender: TObject);
var
        Threaded_Dir,APPLY_NAME,APPLY_REAM_NAME: string;
        FileListName,DirName,FileDate:String;
        FTextFile:file;  //
        lFileSizeOf,j: Word;
        pcBegin, pcEnd, pcNow: pchar;
        pcEndOfString: pchar;
        szLineText: array[0..1024] of char;
        S: string;
begin
        FileDate:=formatdatetime('yyyymmdd',now);//当前系统日期
        HYConfigIni:=TIniFile.Create(GetCurrentDir+'\hongyun.ini');
        Threaded_Dir:=HYConfigIni.ReadString('Threaded', 'Threaded_Dir', '');
        APPLY_NAME:=HYConfigIni.ReadString('Threaded', 'APPLY_NAME', '');
        APPLY_REAM_NAME:=HYConfigIni.ReadString('Threaded', 'APPLY_REAM_NAME', '');
        DirName:=Threaded_Dir+APPLY_NAME+FileDate+'.'+APPLY_REAM_NAME;//文件名
        if AnsiCompareStr(FDate,FileDate)<>0 then //比较字符串
        Begin
                i:=0;
                FDate:=FileDate;
                Memo2.Clear;
                FileCount:=0;
                nCount:=0;
        End;        //读取文件
        if FileExists(DirName) then
        Begin
                AssignFile(FTextFile, DirName); //load file
                Reset(FTextFile, 1); //setting file read only
                lFileSizeOf := FileSize(FTextFile); //获取文件的字节数
                if FileCount=lFileSizeOf then Exit;
                Seek(FTextFile,FileCount ); //定位
                pcBegin := AllocMem(lFileSizeOf*2048);//lFileSizeOfMyTest - FileCount);//AllocMem allocates a block of the given size on the heap
//Reads one or more records from an open file into a variable
                BlockRead(FTextFile, pcBegin^ ,lFileSizeOf - FileCount);
                CloseFile(FTextFile); //关闭文件                //一行一行切割读入的文件内容
                pcNow := pcBegin;
                pcEnd := pcBegin + lFileSizeOf - 1;
                
                if pcNow=nil then Exit;
                while pcNow  < pcEnd  do
                begin
                        pcEndOfString := StrPos(pcNow, #13#10);
                        if pcEndOfString = nil then pcEndOfString := pcEnd;
                        StrLCopy(@szLineText, pcNow, pcEndOfString - pcNow);
                        i:=Memo2.Lines.Count + 1;
                        Memo2.Lines.Add(IntToStr(i)+'    '+StrPas(szLineText));
                        pcNow := pcEndOfString + 2;
                end;
                FreeMem(pcBegin);
                FileCount:=lFileSizeOf + 1;//获得当前文件的指针
         End;
end;******************************************
procedure TForm1.FormShow(Sender: TObject);
var
   Threaded_Hour,Threaded_Minute,Threaded_Second:integer;
begin
        HYConfigIni:=TIniFile.Create(GetCurrentDir+'\hongyun.ini');
        Threaded_Hour:=StrToInt(HYConfigIni.ReadString('Threaded', 'Threaded_Hour', ''));
        Threaded_Minute:=StrToInt(HYConfigIni.ReadString('Threaded', 'Threaded_Minute', ''));
        Threaded_Second:=StrToInt(HYConfigIni.ReadString('Threaded', 'Threaded_Second', ''));
        FileCount:=0;
        i:=0;
        nCount:=0;
        Memo2.ReadOnly:=true;
        FDate:=formatdatetime('yyyymmdd',now);
        timer1.Interval:=(Threaded_Hour*60*60+Threaded_Minute*60+Threaded_Second)*1000;
end;
这就是我的源代码了,有时可以取到数据,有时就不行,小弟很菜,大哥帮帮忙,谢谢!

解决方案 »

  1.   

    其实可以使用未公开函数来监视文件的改变:http://dev.csdn.net/develop/article/3/3297.shtm
      

  2.   

    SHChangeNotifyRegister对于使用某些操作不行的
    例如用CMD.exe控制台的,Copy,Del,它没响应的
      

  3.   

    对这些可以使用下面的方法来监控:http://dev.csdn.net/develop/article/3/3487.shtm
      

  4.   

    Delphi组件面板Sample页有个TShellChangeNotifier组件,设置工作目录和OnChange事件即可
      

  5.   

    具体触发选项可设置其NotifyFilter属性
      

  6.   

    小弟还是不明白,我没有使用过TShellChangeNotifier,不知道这么用,此组件是用来作甚么的,能否举个例子,谢谢!实在不行我只有一个字节一个字节的去读取了,这样可能很慢,如果文件里有上万行记录,我是想能否有个好的方法,哪位大侠知道???而且我读的文件是再共享目录中的,如在Linux上共享出来的目录(通过Samba来设置共享目录,我只有读的权限,没有写的权限),还需要设置登陆共享目录(输入姓名和密码),唉,大哥帮帮忙.