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 }
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 }
哈哈
哈哈、、、、、、、、、、、、、、、、、、、、、、
今天太闲了,所以尝试一回一天在电脑前看贴的经历
juliens(星星球愛思纯^_^)I 服了 you!
哈哈、、、、、、、、、、、、、、、、、、、、、、
今天太闲了,所以尝试一回一天在电脑前看贴的经历
____________________________________________________________________你平时不闲的时候不在电脑前看贴???
做Java多一些。而我上面说的是一个白天都在看贴呀,不过还是做不到,刚才又跑去
玩了。请楼主结贴吧。