【已解决】读取文本文件大于 64KB 就出错!
本帖最后由 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#
$tx1 = FileReadLine($file);按行读取不限 没这限制,况且这么小的值。估计是你的文件问题~ 文件读取受限于字符串的最大长度:2,147,483,647 。读取错误可能是文件编码问题。可以设置成自动识别编码。FileOpen("文件名", $FO_FULLFILE_DETECT) qq413774005 发表于 2023-8-17 10:02
$tx1 = FileReadLine($file);按行读取不限
刚才测试了一下读取某天的服务器记录,TXT格式413MB,可以读出来有30+万行。
但是写入数组时报错了:Line 9185,Error:数组超出界限
当然可以尝试其他的形式来保存读取的数据 afan 发表于 2023-8-16 19:18
没这限制,况且这么小的值。估计是你的文件问题~
64KB 文本文件被限制问题已附代码,请a大帮忙看看,谢谢! 附上完整代码,修改文本文件名称。问题未结贴 这就不是 FileRead 读取多少的问题了,而是 MultiByteToWideChar 的问题 (官方也有说明,调用此函数很容易导致缓冲区溢出)。
既然 65536 正常,那就简单以该数值分段代入好了。
当然也可以试试参1代入结构而不是字符串。 本帖最后由 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 修改。创建时直接赋值,控件创建失败。
不过文档是中文字符串就会报错。
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) 1、FileOpen的第2个参数512是什么意思,没看到有这个值啊。
2、GUICtrlCreateEdit创建的时候赋值为空,去掉样式,后面用GUICtrlSetData赋值试试。
3、GUICtrlSetLimit这个命令了解一下
4、au3的BinaryToString已经可以应付编码问题了,没必要用_WinAPI_WideCharToMultiByte吧 haijie1223 发表于 2023-8-22 00:30
1、FileOpen的第2个参数512是什么意思,没看到有这个值啊。
2、GUICtrlCreateEdit创建的时候赋值为空,去 ...
512 是 ANSI
2、3 必须的
4 他这是转换为繁体系统使用的文本(代码页950),所以光靠BinaryToString估计不行,因为有CodePage的参与,不是简单的ANSI、UTF等等那几个值。
BTW, LZ对自己的帖子不太积极跟帖回复,不然第一时间就解决了,哪需要拖一个星期…… afan 发表于 2023-8-22 09:06
512 是 ANSI
2、3 必须的
4 他这是转换为繁体系统使用的文本(代码页950),所以光靠BinaryToString估计 ...
这个代码就差一个文本文件没上传,谁都可以测试。
还想着 a 大直接给我改好了贴上来呢?!:face (24): chishingchan 发表于 2023-8-22 09:44
这个代码就差一个文本文件没上传,谁都可以测试。
还想着 a 大直接给我改好了贴上来呢?!
代码也是过了几天才贴出来的,之前表达是 FileRead 读取问题
也有 gyp2000 回复了,你也没回复是否合意
我也说过个人想法,也没见你回复是否尝试了,结果如何了…… 本帖最后由 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