如何快速读取到最后一行

pppplato 2005-10-25 01:30:35
在一个一行一条记录的文件中,如何快速读取他的最后一行.


如何按行数来分割文件?
即把一个有500行的文件分割成,两个各250行的小文件
...全文
439 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjjf 2005-10-28
  • 打赏
  • 举报
回复
to cozmic : 用按照斐波那数列增长会更优雅。
cozmic 2005-10-27
  • 打赏
  • 举报
回复
还是觉得我的方法比较优雅
cozmic 2005-10-27
  • 打赏
  • 举报
回复
我觉得,应该直接设置一个缓冲快,初始值约256Bytes,将文件末尾256B读入其中,
然后split("/t|/n"),如果所得为一个字符数组,那么证明最后一行大约256 B,那么扩大一倍缓冲块,读入,再splip,直至出现两个以上字符数组,那么最后一个就是最后一行的内容。
Mark_Chen 2005-10-26
  • 打赏
  • 举报
回复
支持ztc16627(无语) 得解答!
OnlyFor_love 2005-10-26
  • 打赏
  • 举报
回复
有规则的文件可以按照楼上大虾的方法,不过一般的文件读取的话很困难!
ztc16627 2005-10-26
  • 打赏
  • 举报
回复
用RandomAccessFile.如果文件中的记录比较规则,可以比较方便地读最后一行.
这是一个例子:
import java.io.*;

public class TestRandomAccess{
public static void main(String args[])throws IOException{
RandomAccessFile rf = new RandomAccessFile("test.txt", "rw");

rf.seek(3*14);

System.out.println(rf.readLine());

rf.close();
}
}

test.txt有15行,每行有3个bytes.所以读最后一行,用seek(3*14)就可以了
sjjf 2005-10-26
  • 打赏
  • 举报
回复
二分法是肯定不行的,即使是比二分法高效很多的斐波那搜索也不行。
因为只是需要查找最后的几行的没必要把侧重点放在全局。

上面我的算法大致如下:

int iBlock = 80;
RandomAccessFile rf = new RandomAccessFile("test.txt", "rw");
int iFileLen = rf.length();

int iPos = iBlock;
byte[] abtTmp = new byte[iBlock];
int iLineSize = 2048;
byte[] abtLastLine = new byte[iLineSize];
iCount = iLineSize -1;
while(!exitFalg)
{
if (iFileLen - iPos <0) return ; //读到开头了。
rf.seek(iFileLen - iPos);
int iReads = rf.read(iTmp);
//处理读写异常的代码....
for(int i = iReads ;i >= 0;i--)
{
if (iTmp[i]!='\n') //匹配换行符号,不同系统可能不一致。
abtLastLine[iCount--] = iTmp[i];
else
{
exitFalg = ture;
break;
}
}
iPos += iBlock;
}

String strLastLine = new String(abtLastLine,iCount,iLineSize - iCount);
sjjf 2005-10-26
  • 打赏
  • 举报
回复
估算一下你的最后一行的最大值。比如假定是RowMax
-----
这个什么意思,怎么估算


----这个只能根据现实的情况来做了,
比如业务中根本就没有超过 80个字节的一行的数据。
那么可以设定为 80 或者稍微大一点。
这个不通用。但可以减少i/o次数

如果你想做的通用一点。
那么可以倒过来读,
每次读一个block(大小自定义),当然你也可以一个字节一个字节的读(不考虑效率的话)。
直到读到的内容中有换行符。








believefym 2005-10-26
  • 打赏
  • 举报
回复
楼上的算法也不太好吧,你这个seek不能保证seek到一行的起始位置
不知道你怎么处理呢?
cozmic 2005-10-26
  • 打赏
  • 举报
回复
利用二分法,每次读到文件大小的一半,然后顺次检查换行符(/t|/n)的个数,大于二就再分,依此循环。设文件为n个字节,则最多需要 [log(2) n] + 1 次
believefym 2005-10-26
  • 打赏
  • 举报
回复
估算一下你的最后一行的最大值。比如假定是RowMax

-----

这个什么意思,怎么估算
sjjf 2005-10-26
  • 打赏
  • 举报
回复
读最后一行倒是有个本办法。
前提:
1.文件的大小能获取到。RandomAccessFile.length()
2.文件可以随机访问。 RandomAccessFile.seek()

算法描述:
估算一下你的最后一行的最大值。比如假定是RowMax
seek到 fileLength - rowMax的位置。
然后读到文件尾部。
在内存中查找下最后一个换行符的位置即可。
这种做法应该会很快。
believefym 2005-10-26
  • 打赏
  • 举报
回复
笨一点的方法就是循环读取readLine,返回最后一行
majy 2005-10-25
  • 打赏
  • 举报
回复
呵呵,无序的文件不好办,要不你再加一个文件来描述那个文件好了,这样有了额外的信息就比较好办了

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧