function ScanFile(const FileName: string; const Sub: string; caseSensitive: Boolean): Longint;constBufferSize = $8001; { 32K+1 bytes }varpBuf, pEnd, pScan, pPos: PChar;filesize : LongInt;bytesRemaining : LongInt;bytesToRead : Integer;F : file;SearchFor : PChar;oldMode : Word;begin{ assume failure }Result := -1;if (Length(Sub) = 0) or (Length(FileName) = 0) then Exit;SearchFor := nil;pBuf := nil;{ open file as binary, 1 byte recordsize }AssignFile(F, FileName);oldMode := FileMode;FileMode := 0; { read-only access }Reset(F, 1);FileMode := oldMode;try { allocate memory for buffer and pchar search string }SearchFor := StrAlloc(Length(Sub) + 1);StrPCopy(SearchFor, Sub);if not caseSensitive then { convert to upper case }AnsiUpper(SearchFor);GetMem(pBuf, BufferSize);filesize := System.Filesize(F);bytesRemaining := filesize;pPos := nil;while bytesRemaining > 0 dobegin{ calc how many bytes to read this round }if bytesRemaining >= BufferSize thenbytesToRead := Pred(BufferSize)elsebytesToRead := bytesRemaining;{ read a buffer full and zero-terminate the buffer }BlockRead(F, pBuf^, bytesToRead, bytesToRead);pEnd := @pBuf[bytesToRead];pEnd^ := #0;pScan := pBuf;while pScan < pEnd dobeginif not caseSensitive then { convert to upper case }AnsiUpper(pScan);pPos := StrPos(pScan, SearchFor); { search for substring }if pPos <> nil thenbegin { Found it! }Result := FileSize - bytesRemaining + Longint(pPos) - Longint(pBuf);Break;end;pScan := StrEnd(pScan);Inc(pScan);end;if pPos <> nil then Break;bytesRemaining := bytesRemaining - bytesToRead;if bytesRemaining > 0 thenbeginSeek(F, FilePos(F) - Length(Sub));bytesRemaining := bytesRemaining + Length(Sub);end;end; { While }finallyCloseFile(F);if SearchFor <> nil then StrDispose(SearchFor);if pBuf <> nil then FreeMem(pBuf, BufferSize);end;end; { ScanFile }

解决方案 »

  1.   

    cjml上面的文件内字符查找算法,搂主还是看着帮助自己慢慢看吧
      

  2.   

    //扫描文件:文件名,子字符串,是不是对大小写敏感,返回长整形,返回-1表示失败
    function ScanFile(const FileName: string; const Sub: string; caseSensitive: Boolean): Longint;
    const
    //缓冲区大小32K+1 bytes 
    BufferSize = $8001; { 32K+1 bytes }var
    //字符型指针
    pBuf, pEnd, pScan, pPos: PChar;
    //文件尺寸
    filesize : LongInt;
    //保留字节数
    bytesRemaining : LongInt;
    //将要读取的字节
    bytesToRead : Integer;
    //文件类型,和磁盘中某个文件联系起来
    F : file;
    //正在执著的位置
    SearchFor : PChar;
    //文件状态
    oldMode : Word;begin{ assume failure }
    开始时假定为失败
    Result := -1;
    如果了字符串和文件名为空,则退出函数
    if (Length(Sub) = 0) or (Length(FileName) = 0) then Exit;
    初始化下面两个状态
    SearchFor := nil;
    pBuf := nil;
    以二进制形式1字节为单位打开文件,
    { open file as binary, 1 byte recordsize }
    和指定文件联系起来,现在F可以代表文件名为FileName的文件了
    AssignFile(F, FileName);
    保存老的文件属性,这个变量在哪里声明的??
    oldMode := FileMode;
    设定文件属性为只读访问
    FileMode := 0; { read-only access }
    这个是否有问题,参数应该只有一个即F:打开文件F
    Reset(F, 1);
    把刚才的文件属性返回给当前的文件属性
    FileMode := oldMode;
    分配内存给缓冲区,搜索字符
    try { allocate memory for buffer and pchar search string }
    分配字符空间,以Sub的长度加1为尺寸
    SearchFor := StrAlloc(Length(Sub) + 1);
    将Sub字符串复制给SearchFor
    StrPCopy(SearchFor, Sub);
    如果不区分字母大小写
    if not caseSensitive then { convert to upper case }
    则把SearchFor全变为大字
    AnsiUpper(SearchFor);
    分配BufferSize字节给pBuf。
    GetMem(pBuf, BufferSize);
    得到F文件的尺寸以字节为单位
    filesize := System.Filesize(F);
    将这个文件大小的值赋给bytesRemaining 
    bytesRemaining := filesize;
    位置值先初始化为空
    pPos := nil;
    当bytesRemaining(即文件大小的值)大于0时,进行以下循环
    while bytesRemaining > 0 dobegin{ calc how many bytes to read this round }
    如果bytesRemaining >= BufferSize 
    if bytesRemaining >= BufferSize then
    则bytesToRead 等于BufferSize+1;
    bytesToRead := Pred(BufferSize)
    不然
    else
    则bytesToRead 等于bytesRemaining;
    bytesToRead := bytesRemaining;{ read a buffer full and zero-terminate the buffer }
    把文件中bytesToRead大小的读进pBuf^中
    BlockRead(F, pBuf^, bytesToRead, bytesToRead);
    pBuf[bytesToRead]的地址赋给pEnd 
    pEnd := @pBuf[bytesToRead];
    将Pend的值赋为#0。这样之后,事实上pBuf就是以#0为结束了。
    pEnd^ := #0;pScan := pBuf;
    当pScan没有到结尾时。开始循环
    while pScan < pEnd dobegin
    如果不区分大小字,将pScan的值全变大写
    if not caseSensitive then { convert to upper case }AnsiUpper(pScan);
    以PPos来取得pScan中的SearchFor(即SubString)的位置
    pPos := StrPos(pScan, SearchFor); { search for substring }
    如果在SearchFor找到,pPos必不为空
    if pPos <> nil then
    begin { Found it! }
    则该函数的返回值是该子串在文件尺寸中的位置
    Result := FileSize - bytesRemaining + Longint(pPos) - Longint(pBuf);
    然后退出循环结束
    Break;
    end;
    将pScan移到pScan指向的字符串的结尾处,再进一步,继续循环查找子串
    pScan := StrEnd(pScan);
    Inc(pScan);
    end;
    if pPos <> nil then Break;
    bytesRemaining减去己读过的部分
    bytesRemaining := bytesRemaining - bytesToRead;
    如果bytesRemaining还大于0,即还没有把缓冲区读完
    if bytesRemaining > 0 then
    begin
    则将文件的指针定位到下一个位置,以Sub为单位来减去
    Seek(F, FilePos(F) - Length(Sub));
    bytesRemaining := bytesRemaining + Length(Sub);end;end; { While }
    以下是结束处理
    finally
    关闭文件
    CloseFile(F);
    如果SearchFor 不为空,则除去该串
    if SearchFor <> nil then StrDispose(SearchFor);
    如果pBuf不为空,则释放内存
    if pBuf <> nil then FreeMem(pBuf, BufferSize);end;end; { ScanFile }
      

  3.   

    >> linzhengqun(风) I 服了 you!
    哈哈
      

  4.   

    juliens(星星球愛思纯^_^) I 服了 you!
    哈哈、、、、、、、、、、、、、、、、、、、、、、
    今天太闲了,所以尝试一回一天在电脑前看贴的经历
      

  5.   

    回复人:linzhengqun(风) ( 五级(中级)) 信誉:100  2004-07-28 15:22:00  得分:0
     
    juliens(星星球愛思纯^_^)I 服了 you!
    哈哈、、、、、、、、、、、、、、、、、、、、、、
    今天太闲了,所以尝试一回一天在电脑前看贴的经历
    ____________________________________________________________________你平时不闲的时候不在电脑前看贴???
      

  6.   

    TO:Eastunfail(龙子龙孙)==(恶鱼杀手) 真的没有什么时间,我快大学毕业了,面临就业的压力。而Delphi我已经少做了
    做Java多一些。而我上面说的是一个白天都在看贴呀,不过还是做不到,刚才又跑去
    玩了。请楼主结贴吧。