读取文本文件的最后一行内容(100分)

  • 主题发起人 主题发起人 Action
  • 开始时间 开始时间
A

Action

Unregistered / Unconfirmed
GUEST, unregistred user!
有什么好的办法可以以最快速度直接读取文本文件的最后一行内容
 
办法不太好,实在没办法,就用下面的代码。
procedure TForm1.Button1Click(Sender: TObject);
var
sl:tstringlist;
s:string;
begin
sl:=tstringlist.Create;
sl.LoadFromFile('c:/a.txt');
s:=sl[sl.count-1];
end;
 
var
s:string;
f:TextFile;
begin
AssignFile(f, 'e:/temp/temp.txt');
reset(f);
while not eof(f) do
readln(f,s);
end;
 
如果文件不是太大的话,建议用panyongze的方法,效率高得多。
 
panyongze??能具体说说吗?
 
sorry..没注意名字。。呵。。。
如果方件有个1MB.那读的话就很慢了。。
听说fseek可能文件定位。能否用它试试?
 
FileStream 定位到(文件长度 - 64KB),读出 64KB,查找最后一个 CRLF,找到了
就把后面的内存复制到字符串。没找到就继续从前面读取 64KB,并把内存合并。
 
procedure TForm1.Button1Click(Sender: TObject);
var
sl:tstringlist;
s:string;
begin
sl:=tstringlist.Create
//新建一个TStrinList对象的变量。
sl.LoadFromFile('c:/a.txt')
//使用TSTringList对象的方法将文本文件读到内存中去。
s:=sl[sl.count-1]
//读出最未的一行,也就是你所说的最未一行。
end;


我认为这个方法效率不会太高吧!
 
如果你的文本文件,每行的长度是固定的,并且是已知的,就可以直接计算出最后一行的
开始位置,只读出最后一行,速度很快。
如果每行的长度不固定,可以从文件尾部往前读,一直读到有回车符和换行符就可以了,这种
方法比较麻烦,如果文件很大可以考虑这种方法,否则文件不太大,就使用我上面提供的方法吧。
(你是否没看懂代码?S就是最后一行文本。)
 
我用以下方法较快的实现了:

int iFileHandle;
int iFileLength;
char *pszBuffer;


iFileHandle = FileOpen("G://temp.log", fmShareDenyRead);
iFileLength=FileSeek(iFileHandle,-100,2);
pszBuffer = new char[101];
for (int i=0;i<=100;i++)
pszBuffer=' ';
iBytesRead = FileRead(iFileHandle, pszBuffer, 100);
FileClose(iFileHandle);


直接读取最后100个字节
 
有两个问题:
1、你不能保证最后100个字节就一定是最后一行;
2、for (int i=0;i<=100;i++)
pszBuffer=' ';
这段好象效率不够好,不如用String来实现。
var Buffer:String;

Buffer:=StringOfChar(' ',100);
iBytesRead:=FileRead(iFileHandle,Buffer[1],100);

用C的话,Buffer好象不用加'[1]'。
你觉得呢? :)
 
多听听教父的意见有好处。
 
Action:
既然你用了FileSeek和FileBuffer, 你可以按照这个思路倒着查找, 直到找到换行符位置
 
既然都把内容装到缓冲区里去了,找到最后一行还不是轻而易举的事情吗:
function LineStart(Buffer, BufPos: PChar): PChar;
返回只想最后一个回车的 PChar
若没有找到,则返回的指针指向 Buffer

你可以先将最后 100 个字符装入缓冲区,调用该函数,若返回指针指向 Buffer,
侧将该 100 字符转入另一缓冲区,因为这肯定属于最后一行的内容,然后继续
向前读取 100 字符,依此类推……
 
后退
顶部