找回密码
 加入
搜索
查看: 3945|回复: 14

[AU3基础] [已解决]为什么文件永远读不完?

 火.. [复制链接]
发表于 2011-8-25 11:04:18 | 显示全部楼层 |阅读模式
本帖最后由 godhawk 于 2011-8-26 23:50 编辑

我的代码是这样的,就是按行读取一个文本文件
Global $dicline[10000]

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]) < 1  Then
    MsgBox(0,"信息提示", "字符串只包含空白字符.")
        ContinueLoop
EndIf

If @error = -1 Then 
MsgBox(0,"信息提示","文件读完了!")
ExitLoop
EndIf

MsgBox(0,"读取数据","当前行是" & $dicline[$i])

Next

FileClose($dicfile)
结果会一直弹出对话框,“字符串只包含空白字符”,而不会弹出 "文件读完了!"

而事实上,我的那个文本文件,只有5行!

为什么会这样呢?
发表于 2011-8-25 11:23:09 | 显示全部楼层
FileOpen 在循环里?
发表于 2011-8-25 11:30:12 | 显示全部楼层
你这个脚本问题实在太多了点,象:
1. 数组下界超越,应该是:For $i = 0 To 10000 或改为Global $dicline[10001]
2. $dicfile = FileOpen("D:\1.dic", 0)不应该放在循环里
3. If @error = -1 Then 语句根本不可能判断到文件是否读完,Error值是指最近一执行语句的。
.........
发表于 2011-8-25 12:58:39 | 显示全部楼层
1.文件内行数是从1-10000 但是数组是0-9999  ,所以改正方法循环是0 to 9999  对应行数是$i+1
2.open不要出现在循环里 这样加重cpu负担
3.报错提示要出现在$dicline[$i] = FileReadLine($dicfile, $i)的下面,而不是循环的结束
4.整个程序的过程即便没有错误也是不科学的,因为有办法可以一次全部把所有行都读到数组,然后再判断,而不需要一行一行的循环,试试$array=StringRegExp("你要打开的文本",'.*',3)
 楼主| 发表于 2011-8-25 13:38:58 | 显示全部楼层
本帖最后由 godhawk 于 2011-8-25 14:13 编辑

感谢楼上的各位,把 if @error段往上提4行之后,问题解决了!各个小问题也修正了

现在我正在尝试4楼 love5173兄的办法,用StringRegExp()函数
Global $dicline[10000]
$dicfile = FileOpen("D:\1.dic", 0)                 ;载入一个txt文件,但是后缀改为dic
$dicline = StringRegExp(FileRead($dicfile),'.*',3)

For $i = 1 To  UBound($dicline) - 1
        MsgBox(0,"读取数据","当前行是" & $dicline[$i])
Next
这样貌似会出现一个问题,每个换行符号,也作为空白数据,被当做一行读出来了……






.
发表于 2011-8-25 14:56:27 | 显示全部楼层
本帖最后由 netegg 于 2011-8-25 14:59 编辑
#include<array.au3>
_filereadtoarray($file,$aA)
msgbox(0,'linecount',$aA[0])
For $i = 1 To  $aA[0]
        MsgBox(0,"读取数据","当前为第" &$i&"行, 数据是" &$aA[$i])
Next
发表于 2011-8-25 15:31:41 | 显示全部楼层
netegg 发表于 2011-8-25 14:56



#include <file.au3>
发表于 2011-8-25 23:33:25 | 显示全部楼层
回复 7# powerofos


别这样嘛!嘻嘻!
 楼主| 发表于 2011-8-26 00:45:10 | 显示全部楼层
谢谢楼上提供的UDF方法,但是我总是觉得可以用常规函数的情况下,去直接用UDF,太没有技术含量了^^

我又复习了一次正则表达式,发现只要把 .* 改为 .+ 就能正常运行了

果然*会引起把.识别为0,也就是把换行符也匹配进去的可能性……
发表于 2011-8-26 02:23:43 | 显示全部楼层
本帖最后由 netegg 于 2011-8-26 02:28 编辑

不知道正则能不能匹配回车?如果行的话也可以吧

不过很不同意你的说法,udf只是为了使用者更方便使用,没有什么专业不专业之说,难道你做的程序里没有一个是自定义的函数?那些都是udf,包括什么控件点击一类的(当然用消息模式不是udf)
发表于 2011-8-26 08:54:37 | 显示全部楼层
原来这样也可以  学习了  长见识了  谢谢啊
发表于 2011-8-26 09:17:33 | 显示全部楼层
循环fileopen?
发表于 2011-8-26 11:13:06 | 显示全部楼层
回复 9# godhawk
不想用UDF?
如果延用楼主1楼的思想应做如下修改:
#include <array.au3>
$time = TimerInit()
Local $dicline[1], $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[0] = UBound($dicline) - 1;定义数组0为行总数
                MsgBox(0, "信息提示", "文件读完了!")
                ExitLoop
        EndIf
        $i += 1
WEnd
_ArrayDisplay($dicline, TimerDiff($time))
MsgBox(0, "读取数据", "共" & $i - 2 & "行" & @CRLF & "当前行是" & $dicline[$dicline[0]] & @CRLF & "用时:" & TimerDiff($time))
MsgBox(0, "空行", $Error_LineInfo)
FileClose($dicfile)


但以上代码的效率比较低下.如果文件比较大的话会非常非常慢
用楼主在5楼的思路,如果用正则进行分行的话,倒是比较不错的选择,但如此简单的分行用正则似乎又有点杀鸡用牛刀的感觉,并且用正则的效率也不是最高的.做个简单的比较可知.
$time = TimerInit()
;~ Global $dicline[10000]
$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做为分割符.
发表于 2011-8-26 17:37:20 | 显示全部楼层
三笑'但如此简单的分行用正则似乎又有点杀鸡用牛刀的感觉'这话说的太对了,
就好象用正则拆一个字符串,还不够琢磨怎么写正则呢
 楼主| 发表于 2011-8-26 23:48:21 | 显示全部楼层
确实如此,发现用了上面的代码测试,正则表达式明显要慢一些……

看来StringSplit是最佳方法了,再次感谢两位,特别是三笑兄的详细代码,让我受益良多。

结贴吧。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-10-1 17:15 , Processed in 0.083665 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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