ebhb 发表于 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)

basc 发表于 2013-2-15 15:59:36

回复 16# ebhb


    偏离我所需要的了,纠结。。

ebhb 发表于 2013-2-15 16:02:04

你不是要读取文本文件的最后一行吗?

happytc 发表于 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)就读到最后一行了。

ebhb 发表于 2013-2-16 10:37:08

学习了,大文件操作很少,所以没什么经验。

xms77 发表于 2013-2-16 10:44:01

回复 19# happytc
Happy兄,有没有用内存映射读取大文本文件的列子,这个很有用啊!

happytc 发表于 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 ;得到:内存分配粒度
$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)

haijie1223 发表于 2013-2-16 13:37:11

返回值一般都有error吧~

fhqbbfcu2050 发表于 2013-2-17 22:03:09

正则强大,看不懂。。。。

bsdos 发表于 2013-2-18 09:40:55

正则的意思大概就是用回车换行来确定最后一行

haijie1223 发表于 2013-2-18 10:35:20

看下 @error 值

jojomecool 发表于 2013-2-18 14:02:36

正则,果然不同反响
页: 1 [2]
查看完整版本: 如何读取读取TXT文本的最后一行