向各位路过的老师请教下关于文件行数及数组问题[已解决]
本帖最后由 annybaby 于 2011-5-20 00:31 编辑具体描述如下:
我经常需要处理一些文本文件,将文件逐行读出,并将它放到一个数组里面进行后续的处理,文件的行数会有比较大的差别,怎样得到这个行数及申请数组的会比较好呢?
我知道,可以用一个循环来读取,定义一个记录行数的变量,每读一行就加1,直至文件末尾,或者直接用自定义函数_FileCountLines(),还有其它好一点的方法吗?主要考虑的是代码长度,资源占用,执行效率以及编译后文件的大小,特别是数组申请问题,每次都处理不好,太大的话觉得浪费系统资源(会吗?)太小又容易越界~ 现成的函数呀:
#include <File.au3>
#include <Array.au3>
Local $Array
_FileReadToArray("F:\test.txt", $Array)
_ArrayDisplay($Array)
#include <Array.au3>
Local $sText = FileRead("test.txt")
Local $asResult = StringRegExp($sText, '(.*)\r\n', 3)
_ArrayDisplay($asResult, "行数: " & UBound($asResult))
Exit 回复 2# happytc
这个只是显示出来吧?我还要对数据进程比较复杂的处理的,如说,要对每行数据进行分割,对其中一部分进行运算,交换位置等 本帖最后由 love5173 于 2011-5-19 23:58 编辑
回复 1# annybaby
关于这个问题,我也没有搜索别人的回答,我是这么理解的
搜索整个文本内的换行也就是\n的个数,理想状态下最后一行是没有换行符的,也就是搜索\n的个数+1 就是整个文本的行数,但是考虑到有的文本不是很整齐,里面会夹杂着好几个换行的情况,这时要先把连续的换行替换为一个换行,也就是\n{2,}替换为\n,但是这样仍然存在着最后一行后面或许还是有一个换行,这样就需要判断最后一个换行后面还有没有字符,索性开始的时候直接给最后一行加上一个换行就是了,经过替换后,含有的换行个数就是楼主要的内容了。
代码如下$con=UBound(StringRegExp(StringRegExpReplace(FileRead("txt.txt")&@CRLF,'(\n){2,}','\1'),'\n',3))
考虑的代码做过的运算内容未必有楼主说的快,希望楼主经过测试后,觉得满意再使用
另外,楼主只是为了要把每行都读到数组里面的话,可以用
$array=StringRegExp(fileread("txt.txt"),'[^\n]+',3)
$con=UBound($array)来实现,当然,也有现成的UDF 本帖最后由 annybaby 于 2011-5-20 00:02 编辑
回复 3# easefull
这个不错,我看了一下,自定义函数_FileCountLines()也是通过正则来计算行数,不过调用的话会多打开一次函数,所以直接用前面已经打开的应该会快一些,呵呵,谢谢指教~~
不过总行数是比数组长度UBound()大1,因为最后一行是没有回车换行的~~ 回复 4# annybaby
它已经把每行读到一个数组元素里,第一个元素是这个文件里有多少行
这样,无论你怎样复杂操作,你不就是对这个数组进行操作就可以了
怎么叫“显示”出来呢????? 本帖最后由 love5173 于 2011-5-20 00:01 编辑
回复 3# easefull
你的代码表面看起来没有问题,但是如果你能看看我上面说的内容的话就会发现,你的代码存在致命的缺陷,5楼的代码已经更新,你可以看看下面那个,
经过我对10010行文件的测试,我的第一个取行数的代码,比第二个慢了一倍差不多,呵呵!
你的正则有问题,要么改正则,如果非要这么写,那么就要做我上面说的做换行的处理 回复 8# love5173
\r\n分行,你是用的\n分行.
很难说谁的代码存在致使的缺陷 本帖最后由 love5173 于 2011-5-20 00:24 编辑
回复 9# 3mile
欢迎测试,我希望你能看完我的5楼再说。如果你的最后一行根本后面就没有换行符呢,你是怎么判断的?这不是致命缺陷吗?
而我用的\n也不是绝对的,要根据实际的文件处理,因为我处理的是txt,作为txt 3M应该知道换行是\n\r,我的代码绝对没有问题!
如果你找出错误我愿意给你道歉!
更正一下@crlf 是\r\n , 其实无论是\r\n 还是\n\r 都不会影响我的第一行代码的计算的,当然那个确实慢。
5楼我是给的两个代码,第一行只是一个思路而已,目的不是在于那句代码,而是在给大家说一些事情而已。
授人以鱼不如授人以渔! 回复 10# love5173
File.au3里的这段函数已经很说明问题了.
Func _FileCountLines($sFilePath)
Local $hFile = FileOpen($sFilePath, $FO_READ)
If $hFile = -1 Then Return SetError(1, 0, 0)
Local $sFileContent = StringStripWS(FileRead($hFile), 2)
FileClose($hFile)
Local $aTmp
If StringInStr($sFileContent, @LF) Then
$aTmp = StringSplit(StringStripCR($sFileContent), @LF)
ElseIf StringInStr($sFileContent, @CR) Then
$aTmp = StringSplit($sFileContent, @CR)
Else
If StringLen($sFileContent) Then
Return 1
Else
Return SetError(2, 0, 0)
EndIf
EndIf
Return $aTmp
EndFunc ;==>_FileCountLines
你的那段代码只考虑了@LF, @CRLF作为换行的处理.难道@CR不能作为换行?
不是想要你给谁道歉才写的这段. 回复 11# 3mile
关于对换行符的支持问题,我想你比我更了解,作为TXT换行的话,你说有几种形式? 谢谢楼上几位老师的热心解答~~{:face (316):} 回复3mile
关于对换行符的支持问题,我想你比我更了解,作为TXT换行的话,你说有几种形式?
love5173 发表于 2011-5-20 00:28 http://www.autoitx.com/images/common/back.gif
你当然比我了解的多,请教 本帖最后由 love5173 于 2011-5-20 00:44 编辑
其他文件类型我不清楚,但是我电脑上txt的换行都是0d0a
算了,不想争什么了,我会努力学习的!同时我也承认我的代码有致命的缺陷!以后也不会乱说话了!
页:
[1]
2