[已解决]为什么文件永远读不完?
本帖最后由 godhawk 于 2011-8-26 23:50 编辑我的代码是这样的,就是按行读取一个文本文件
Global $dicline
For $i = 1 To 10000
$dicfile = FileOpen("D:\1.dic", 0) ;载入一个txt文件,但是后缀改为dic
$dicline[$i] = FileReadLine($dicfile, $i)
If StringIsSpace($dicline[$i]) Or StringLen ($dicline[$i]) < 1Then
MsgBox(0,"信息提示", "字符串只包含空白字符.")
ContinueLoop
EndIf
If @error = -1 Then
MsgBox(0,"信息提示","文件读完了!")
ExitLoop
EndIf
MsgBox(0,"读取数据","当前行是" & $dicline[$i])
Next
FileClose($dicfile)
结果会一直弹出对话框,“字符串只包含空白字符”,而不会弹出 "文件读完了!"
而事实上,我的那个文本文件,只有5行!
为什么会这样呢?{:face (319):} FileOpen 在循环里? 你这个脚本问题实在太多了点,象:
1. 数组下界超越,应该是:For $i = 0 To 10000 或改为Global $dicline
2. $dicfile = FileOpen("D:\1.dic", 0)不应该放在循环里
3. If @error = -1 Then 语句根本不可能判断到文件是否读完,Error值是指最近一执行语句的。
......... 1.文件内行数是从1-10000 但是数组是0-9999,所以改正方法循环是0 to 9999对应行数是$i+1
2.open不要出现在循环里 这样加重cpu负担
3.报错提示要出现在$dicline[$i] = FileReadLine($dicfile, $i)的下面,而不是循环的结束
4.整个程序的过程即便没有错误也是不科学的,因为有办法可以一次全部把所有行都读到数组,然后再判断,而不需要一行一行的循环,试试$array=StringRegExp("你要打开的文本",'.*',3) 本帖最后由 godhawk 于 2011-8-25 14:13 编辑
感谢楼上的各位,把 if @error段往上提4行之后,问题解决了!各个小问题也修正了
现在我正在尝试4楼 love5173兄的办法,用StringRegExp()函数Global $dicline
$dicfile = FileOpen("D:\1.dic", 0) ;载入一个txt文件,但是后缀改为dic
$dicline = StringRegExp(FileRead($dicfile),'.*',3)
For $i = 1 ToUBound($dicline) - 1
MsgBox(0,"读取数据","当前行是" & $dicline[$i])
Next
这样貌似会出现一个问题,每个换行符号,也作为空白数据,被当做一行读出来了……
. 本帖最后由 netegg 于 2011-8-25 14:59 编辑
#include<array.au3>
_filereadtoarray($file,$aA)
msgbox(0,'linecount',$aA)
For $i = 1 To$aA
MsgBox(0,"读取数据","当前为第" &$i&"行, 数据是" &$aA[$i])
Next
netegg 发表于 2011-8-25 14:56 http://www.autoitx.com/images/common/back.gif
#include <file.au3> 回复 7# powerofos
{:face (269):}别这样嘛!嘻嘻! 谢谢楼上提供的UDF方法,但是我总是觉得可以用常规函数的情况下,去直接用UDF,太没有技术含量了^^
我又复习了一次正则表达式,发现只要把 .* 改为 .+ 就能正常运行了
果然*会引起把.识别为0,也就是把换行符也匹配进去的可能性…… 本帖最后由 netegg 于 2011-8-26 02:28 编辑
不知道正则能不能匹配回车?如果行的话也可以吧
不过很不同意你的说法,udf只是为了使用者更方便使用,没有什么专业不专业之说,难道你做的程序里没有一个是自定义的函数?那些都是udf,包括什么控件点击一类的(当然用消息模式不是udf) 原来这样也可以学习了长见识了谢谢啊 循环fileopen? 回复 9# godhawk
不想用UDF?
如果延用楼主1楼的思想应做如下修改:
#include <array.au3>
$time = TimerInit()
Local $dicline, $Error_LineInfo, $i = 1
$dicfile = FileOpen("D:\1.dic", 0) ;载入一个txt文件,但是后缀改为dic
If $dicfile = -1 Then
MsgBox(0, 0, "文件打开错误")
Exit
EndIf
While 1
$temp = FileReadLine($dicfile, $i)
If Not @error Then
ReDim $dicline[$i + 1]
$dicline[$i] = $temp
If StringIsSpace($dicline[$i]) Or StringLen($dicline[$i]) < 1 Then
$Error_LineInfo &= "第" & $i & "行,字符串只包含空白字符." & @CRLF
EndIf
Else
$dicline = UBound($dicline) - 1;定义数组0为行总数
MsgBox(0, "信息提示", "文件读完了!")
ExitLoop
EndIf
$i += 1
WEnd
_ArrayDisplay($dicline, TimerDiff($time))
MsgBox(0, "读取数据", "共" & $i - 2 & "行" & @CRLF & "当前行是" & $dicline[$dicline] & @CRLF & "用时:" & TimerDiff($time))
MsgBox(0, "空行", $Error_LineInfo)
FileClose($dicfile)
但以上代码的效率比较低下.如果文件比较大的话会非常非常慢
用楼主在5楼的思路,如果用正则进行分行的话,倒是比较不错的选择,但如此简单的分行用正则似乎又有点杀鸡用牛刀的感觉,并且用正则的效率也不是最高的.做个简单的比较可知.
$time = TimerInit()
;~ Global $dicline
$dicfile = FileOpen("d:\1.dic", 0) ;载入一个txt文件,但是后缀改为dic
$dicline = StringRegExp(FileRead($dicfile),'.+',3)
FileClose($dicfile)
msgbox(0,0,TimerDiff($time))
$time=TimerInit()
$dicline=StringSplit(FileRead("d:\1.dic"),@CRLF,1+2)
msgbox(0,0,TimerDiff($time))
以上分别用了正则以及StringSplit函数,因为楼主应该是在WINDOWS下进行文本分行,所以只考虑了@CRLF做为分割符. 三笑'但如此简单的分行用正则似乎又有点杀鸡用牛刀的感觉'这话说的太对了,
就好象用正则拆一个字符串,还不够琢磨怎么写正则呢 确实如此,发现用了上面的代码测试,正则表达式明显要慢一些……
看来StringSplit是最佳方法了,再次感谢两位,特别是三笑兄的详细代码,让我受益良多。
结贴吧。
页:
[1]