找回密码
 加入
搜索
查看: 1045|回复: 39

[AU3基础] 【已解决】读取文本文件大于 64KB 就出错!

[复制链接]
发表于 2023-8-16 19:02:06 | 显示全部楼层 |阅读模式
本帖最后由 chishingchan 于 2023-8-23 14:18 编辑
#include <WinAPIConv.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$txtFile = @ScriptDir & "\大于64KB出错.txt"
$txtLang = 950

Local $hFileOpen = FileOpen($txtFile, 512)
Local $sFileRead = FileRead($hFileOpen)        ;, 65536)
FileClose($hFileOpen)

$new = _WinAPI_MultiByteToWideChar($sFileRead, $txtLang, 0, True)
GUICreate("", 640, 480)
Local $idMyedit = GUICtrlCreateEdit($new, 0, 0, 640, 480, $ES_AUTOVSCROLL + $WS_VSCROLL)
GUISetState(@SW_SHOW)
While 1
        Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        ExitLoop
        EndSwitch
WEnd
GUIDelete()
打开并读取一个 2xxKB 的文本文件,当设置读取量 65536 等于 64KB时,运行正常,改大一点就运行出错!

有办法解决吗?

帮助里的备注:过大的 "数量" 可能导致 Autoit 停止和内存分配失败。

答案:30#


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2023-8-17 10:02:59 | 显示全部楼层
$tx1 = FileReadLine($file);按行读取不限

评分

参与人数 1金钱 +50 收起 理由
chishingchan + 50 赞一个!

查看全部评分

发表于 2023-8-16 19:18:54 | 显示全部楼层
没这限制,况且这么小的值。估计是你的文件问题~

评分

参与人数 1金钱 +50 收起 理由
chishingchan + 50 赞一个!

查看全部评分

发表于 2023-8-17 19:04:00 | 显示全部楼层
文件读取受限于字符串的最大长度:2,147,483,647 。读取错误可能是文件编码问题。可以设置成自动识别编码。FileOpen("文件名", $FO_FULLFILE_DETECT)

评分

参与人数 1金钱 +50 收起 理由
chishingchan + 50 赞一个!

查看全部评分

发表于 2023-8-17 22:32:22 | 显示全部楼层
qq413774005 发表于 2023-8-17 10:02
$tx1 = FileReadLine($file);按行读取不限

刚才测试了一下读取某天的服务器记录,TXT格式413MB,可以读出来有30+万行。
但是写入数组时报错了:Line 9185,Error:数组超出界限
当然可以尝试其他的形式来保存读取的数据
 楼主| 发表于 2023-8-20 15:21:21 | 显示全部楼层
afan 发表于 2023-8-16 19:18
没这限制,况且这么小的值。估计是你的文件问题~

64KB 文本文件被限制问题已附代码,请a大帮忙看看,谢谢!
 楼主| 发表于 2023-8-20 15:23:20 | 显示全部楼层
附上完整代码,修改文本文件名称。问题未结贴
发表于 2023-8-20 18:05:38 | 显示全部楼层
这就不是 FileRead 读取多少的问题了,而是 MultiByteToWideChar 的问题 (官方也有说明,调用此函数很容易导致缓冲区溢出)。
既然 65536 正常,那就简单以该数值分段代入好了。
当然也可以试试参1代入结构而不是字符串。
发表于 2023-8-20 21:44:45 | 显示全部楼层
本帖最后由 gyp2000 于 2023-8-20 21:50 编辑

win10 AutoItV3.3.16.1 测试通过。未发现64k内存溢出错误。
#include <WinAPIConv.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$txtFile = @ScriptDir & "\大于64KB出错.txt"
$txtLang = 950

Local $hFileOpen = FileOpen($txtFile, 512)
Local $sFileRead = FileRead($hFileOpen)        ;, 65536)
FileClose($hFileOpen)
$new = _WinAPI_MultiByteToWideChar($sFileRead, $txtLang, 0, True)
GUICreate("", 640, 480)
Local $idMyedit = GUICtrlCreateEdit("", 0, 0, 640, 480, $ES_AUTOVSCROLL + $WS_VSCROLL)
GUISetState(@SW_SHOW)
GUICtrlSetData($idMyedit, $new)
While 1
        Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        ExitLoop
        EndSwitch
WEnd
GUIDelete()

数据太大
需要 GUICtrlSetData 修改。创建时直接赋值,控件创建失败。
不过文档是中文字符串就会报错。
发表于 2023-8-20 22:11:41 | 显示全部楼层
FileRead 返回值就是字符串,并不是多字节字符串。
FileRead 已经在读取的过程中自动解码了。
这样就会导致_WinAPI_MultiByteToWideChar 输入参数错误。那么返回结果估计也是错误的。

例子应该是这样的。
#include <WinAPIConv.au3>
Global Const $CP = 932 ; CP_SHIFT_JIS
Local $sText = "データのダウンロードに失敗しました。"
Local $sMultiByte = _WinAPI_WideCharToMultiByte($sText, $CP, True, False)
$sTest = _WinAPI_MultiByteToWideChar($sMultiByte, $CP, 0, True)
$sOutput = "MultiByte to String" & @TAB & VarGetType($sTest) & " " & StringLen($sTest) & " :" & @CRLF & $sTest & @CRLF & @CRLF
ConsoleWrite($sOutput)
发表于 2023-8-22 00:30:47 | 显示全部楼层
1、FileOpen的第2个参数512是什么意思,没看到有这个值啊。
2、GUICtrlCreateEdit创建的时候赋值为空,去掉样式,后面用GUICtrlSetData赋值试试。
3、GUICtrlSetLimit这个命令了解一下
4、au3的BinaryToString已经可以应付编码问题了,没必要用_WinAPI_WideCharToMultiByte吧
发表于 2023-8-22 09:06:03 | 显示全部楼层
haijie1223 发表于 2023-8-22 00:30
1、FileOpen的第2个参数512是什么意思,没看到有这个值啊。
2、GUICtrlCreateEdit创建的时候赋值为空,去 ...

512 是 ANSI
2、3 必须的
4 他这是转换为繁体系统使用的文本(代码页950),所以光靠BinaryToString估计不行,因为有CodePage的参与,不是简单的ANSI、UTF等等那几个值。

BTW, LZ对自己的帖子不太积极跟帖回复,不然第一时间就解决了,哪需要拖一个星期……

评分

参与人数 2金钱 +159 收起 理由
haijie1223 + 99 受教
tubaba + 60 赞一个!

查看全部评分

 楼主| 发表于 2023-8-22 09:44:08 | 显示全部楼层
afan 发表于 2023-8-22 09:06
512 是 ANSI
2、3 必须的
4 他这是转换为繁体系统使用的文本(代码页950),所以光靠BinaryToString估计 ...

这个代码就差一个文本文件没上传,谁都可以测试。
还想着 a 大直接给我改好了贴上来呢?!
发表于 2023-8-22 10:00:56 | 显示全部楼层
chishingchan 发表于 2023-8-22 09:44
这个代码就差一个文本文件没上传,谁都可以测试。
还想着 a 大直接给我改好了贴上来呢?!

代码也是过了几天才贴出来的,之前表达是 FileRead 读取问题
也有 gyp2000 回复了,你也没回复是否合意
我也说过个人想法,也没见你回复是否尝试了,结果如何了……
发表于 2023-8-22 10:05:05 | 显示全部楼层
本帖最后由 qq413774005 于 2023-8-22 10:10 编辑
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>

$txtFile = @ScriptDir & "\大于64KB出错.txt"
$txtLang = 9500;读取最大行
$n = 0
;----------------------------------------------------
$Form1 = GUICreate("", 640, 505)
Local $idMyedit = GUICtrlCreateEdit("", 0, 0, 640, 480, $ES_AUTOVSCROLL + $WS_VSCROLL)
GUICtrlSetLimit($idMyedit, 100000000);解除edit控制限制为1亿字符
;任务栏
$StatusBar1 = _GUICtrlStatusBar_Create($Form1)
_GUICtrlStatusBar_SetMinHeight($StatusBar1, 25)
_GUICtrlStatusBar_SetText($StatusBar1, "开始")
GUISetState(@SW_SHOW)
;-----------------------------------------------------
Local $hFileOpen = FileOpen($txtFile, 0)
;----------------------------
While 1
        $line = FileReadLine($hFileOpen)
        If @error = -1 Then
                FileClose($hFileOpen);文本文件读取异常就关闭
                ExitLoop
        EndIf
        If $n > $txtLang Then
                ExitLoop
        Else
                GUICtrlSetData($idMyedit, $line & @CRLF, 0)
                _GUICtrlStatusBar_SetText($StatusBar1, $n & "行")
        EndIf
        $n = $n + 1
        ;----------------------------------
WEnd
;----------------------------
FileClose($hFileOpen);文本文件读取异常就关闭

While 1
        Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        ExitLoop
        EndSwitch

WEnd

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-2 07:51 , Processed in 0.099434 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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