找回密码
 加入
搜索
楼主: basc

[系统综合] 如何读取读取TXT文本的最后一行

 火.. [复制链接]
发表于 2013-2-15 15:55:33 | 显示全部楼层
正则很强大,但效率有点低,比如50M的,必须全部读进来然后再正则。我觉得我这个效率应该可以,从文件的最后向前读,遇到0a就是最后一行
$f="t.txt"
$file = FileOpen($f, 0)
; 检查打开的文件是否可读
If $file = -1 Then
    MsgBox(0, "错误", "不能打开文件.")
    Exit
EndIf
; 每次读取一行文本,直到文件结束.
$n1=0
$n2=0
$n3=0
$size = FileGetSize($f)
While $n3 < $size
        FileSetPos($file,$size-$n3+1,0)
    $c = FileRead($file,1)
        If $c=Chr(10) Then
        $n1=FileGetPos($File)
        $n2=$n2+1
        
EndIf
        If $n2=2 Then ExitLoop
    If @error = -1 Then ExitLoop
        $n3=$n3+1
Wend

    $line = FileReadLine($file)
    MsgBox(0, "最后一行", $line)
FileClose($file)
 楼主| 发表于 2013-2-15 15:59:36 | 显示全部楼层
回复 16# ebhb


    偏离我所需要的了,纠结。。
发表于 2013-2-15 16:02:04 | 显示全部楼层
你不是要读取文本文件的最后一行吗?
发表于 2013-2-16 09:49:48 | 显示全部楼层
回复 16# ebhb


若是真正要操作大文件,最好的方式就是:
这种情况必须得用内存映射,何况你是以标准文件方式打开的,au3的系列文件操作函数其实就是调用C/C++里面的fopen,fread,ftell,fseek等函数而已,而C++运行库需要将\r\n替换为\n等额外操作,而且还需要读入C/C++库的内部Buffer,效率是很低的。一般10MB以上的文件最好就用磁盘映射。
用CreateFile打开文件,并CreateFileMapping映射,配合MapOfView可以一次只映射文件的一部分。用内存文件映射的话,Windows会协调磁盘I/O缓冲区策略,而且不需要从文件开头逐字节读入Buffer,文件越大速度越快。有时比C/C++标准文件要快好几倍以上。

======================================
加外,若要用FileReadLine函数,其实不用这么麻烦的。
因其内部一直在用fseek判断是否到了EOF,所以你直接用FileReadLine($file, -1)就读到最后一行了。
发表于 2013-2-16 10:37:08 | 显示全部楼层
学习了,大文件操作很少,所以没什么经验。
发表于 2013-2-16 10:44:01 | 显示全部楼层
回复 19# happytc
Happy兄,有没有用内存映射读取大文本文件的列子,这个很有用啊!
发表于 2013-2-16 13:27:26 | 显示全部楼层
回复 21# xms77

那就给个‘获取一个超大文件偏移量’的例子’吧
将下面代码中的$sFile换成你自己机子有的G级文件

#include <APIConstants.au3>
#include <WinAPIEx.au3>
Local $iRead
$sFile = "d:\GhostXP\C_WinXP.GHO" ;指定你自己机子里的一个超大文件,最好2G以上,小文件会报内存错误
$iToRead = 32 ;读取字节数
$iOffset = 234567 ;偏移量
$aSysInfo = _WinAPI_GetSystemInfo()
$iMemGran = $aSysInfo[7] ;得到:内存分配粒度
$iOffset_Slice = Round(Floor($iOffset / $iMemGran)) * $iMemGran ;偏移量必须是分配粒度的倍数
ConsoleWrite("$iOffset_Slice " & @TAB & @TAB & $iOffset_Slice & @CRLF)
$iOffset_Slice_Size = $iOffset - $iOffset_Slice
ConsoleWrite("$iOffset_Slice_Size " & @TAB & $iOffset_Slice_Size & @CRLF)
$hFile = _WinAPI_CreateFileEx($sFile, 3, 0x80000000, 7, 0x08000000)
$hMapping = _WinAPI_CreateFileMapping($hFile, 0, '', $PAGE_READONLY)
$pAddress = _WinAPI_MapViewOfFile($hMapping, $iOffset_Slice, $iOffset_Slice_Size + $iToRead, $FILE_MAP_READ)
$tBuffer = DllStructCreate('byte[' & $iToRead & ']', $pAddress + $iOffset_Slice_Size)
ConsoleWrite(DllStructGetData($tBuffer, 1) & @CRLF)
_WinAPI_UnmapViewOfFile($pAddress)
_WinAPI_CloseHandle($hMapping)
_WinAPI_CloseHandle($hFile)

发表于 2013-2-16 13:37:11 | 显示全部楼层
返回值一般都有error吧~
发表于 2013-2-17 22:03:09 | 显示全部楼层
正则强大,看不懂。。。。
发表于 2013-2-18 09:40:55 | 显示全部楼层
正则的意思大概就是用回车换行来确定最后一行
发表于 2013-2-18 10:35:20 | 显示全部楼层
看下 @error 值
发表于 2013-2-18 14:02:36 | 显示全部楼层
正则,果然不同反响
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-18 16:17 , Processed in 0.073279 second(s), 14 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表