chishingchan 发表于 2023-8-16 19:02:06

【已解决】读取文本文件大于 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#


qq413774005 发表于 2023-8-17 10:02:59

$tx1 = FileReadLine($file);按行读取不限

afan 发表于 2023-8-16 19:18:54

没这限制,况且这么小的值。估计是你的文件问题~

gyp2000 发表于 2023-8-17 19:04:00

文件读取受限于字符串的最大长度:2,147,483,647 。读取错误可能是文件编码问题。可以设置成自动识别编码。FileOpen("文件名", $FO_FULLFILE_DETECT)

不是小灵通 发表于 2023-8-17 22:32:22

qq413774005 发表于 2023-8-17 10:02
$tx1 = FileReadLine($file);按行读取不限

刚才测试了一下读取某天的服务器记录,TXT格式413MB,可以读出来有30+万行。
但是写入数组时报错了:Line 9185,Error:数组超出界限
当然可以尝试其他的形式来保存读取的数据

chishingchan 发表于 2023-8-20 15:21:21

afan 发表于 2023-8-16 19:18
没这限制,况且这么小的值。估计是你的文件问题~

64KB 文本文件被限制问题已附代码,请a大帮忙看看,谢谢!

chishingchan 发表于 2023-8-20 15:23:20

附上完整代码,修改文本文件名称。问题未结贴

afan 发表于 2023-8-20 18:05:38

这就不是 FileRead 读取多少的问题了,而是 MultiByteToWideChar 的问题 (官方也有说明,调用此函数很容易导致缓冲区溢出)。
既然 65536 正常,那就简单以该数值分段代入好了。
当然也可以试试参1代入结构而不是字符串。

gyp2000 发表于 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 修改。创建时直接赋值,控件创建失败。
不过文档是中文字符串就会报错。

gyp2000 发表于 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)

haijie1223 发表于 2023-8-22 00:30:47

1、FileOpen的第2个参数512是什么意思,没看到有这个值啊。
2、GUICtrlCreateEdit创建的时候赋值为空,去掉样式,后面用GUICtrlSetData赋值试试。
3、GUICtrlSetLimit这个命令了解一下
4、au3的BinaryToString已经可以应付编码问题了,没必要用_WinAPI_WideCharToMultiByte吧

afan 发表于 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对自己的帖子不太积极跟帖回复,不然第一时间就解决了,哪需要拖一个星期……

chishingchan 发表于 2023-8-22 09:44:08

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

这个代码就差一个文本文件没上传,谁都可以测试。
还想着 a 大直接给我改好了贴上来呢?!:face (24):

afan 发表于 2023-8-22 10:00:56

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

代码也是过了几天才贴出来的,之前表达是 FileRead 读取问题
也有 gyp2000 回复了,你也没回复是否合意
我也说过个人想法,也没见你回复是否尝试了,结果如何了……

qq413774005 发表于 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
页: [1] 2 3
查看完整版本: 【已解决】读取文本文件大于 64KB 就出错!