iPAQ 发表于 2012-3-9 09:29:12

[已解决]在将十六进制字符串写磁盘时,用BinaryToString转换后丢失部分字符

本帖最后由 iPAQ 于 2012-3-9 13:54 编辑

我想要将一组十六进制字符串数据写入到磁盘。

在写入过程中,转换时发现经过BinaryToString转换后部分十六进制数变成ASCII码时丢失。

请问是我哪里写错了,还是其他问题?如果这种转换不可靠,有无其他办法写入十六进制字符串?

下面是测试用的部分代码:
;十六进制字符串转ASCII测试
;$Hex="FFFEFDFCFBFA9998979695FFFF"
$Hex=""
For $i = 255 To 1 Step -1
        $Hex=$Hex & Hex($i,2)
Next
MsgBox(0,"10","<[" & $Hex & "]> len=" & StringLen($Hex) & @CRLF & "<[" & BinaryToString("0x" & $Hex,1) & "]> len=" & StringLen(BinaryToString("0x" & $Hex,1)) & @CRLF & "<[" & StringTrimLeft(Binary(BinaryToString("0x" & $Hex,1)),2) & "]> len=" & StringLen(StringTrimLeft(Binary(BinaryToString("0x" & $Hex,1)),2)))
;StringLen将每两个高位ASCII码当做中文字符计算个数。
$Str=BinaryToString("0x" & $Hex,1)
$SecN=1
$tBuffer = DllStructCreate("byte[" & 512*$SecN & "]")
DllStructSetData($tBuffer, 1, $Str)
MsgBox(4096,"set DllStruct","数据结构大小: " & DllStructGetSize($tBuffer) & @CRLF & "数据结构指针: " & DllStructGetPtr($tBuffer) & @CRLF & "Data:" & @CRLF & DllStructGetData($tBuffer, 1))

;然后用下面函数写入磁盘,这里为防误写磁盘注释掉
;_WinAPI_WriteFile($hDisk, DllStructGetPtr($tBuffer), 512*$SecN, $nBytes)
从MsgBox显示的情况就能看到问题。
经过几次试验,发现丢失的字符不是特定字符,而是字符串被剪裁掉了一段。想不明白原因。

smartzbs 发表于 2012-3-9 10:24:13

你在用复杂的方法来实现简单的功能。
$Hex = "CED2B0AED6D0B9FA";我爱中国
FileWrite(@ScriptDir&"\temp.txt", Binary('0x' & $Hex))

iPAQ 发表于 2012-3-9 10:40:50

本帖最后由 iPAQ 于 2012-3-9 12:09 编辑

多谢LS朋友提醒!

是让我弄复杂了,没想到FileWrite也可以直接写磁盘,就是用FileRead和FileSetPos遇到点问题,正在试验。用_WinAPI_SetFilePointerEx和_WinAPI_ReadFile没问题。
就是打开磁盘时只敢用_WinAPI_CreateFileEx,不知道如果用FileOpen写磁盘时会怎么样。

另外把我的代码中的BinaryToString()换成Binary()读写时直接写数据就行,不转换成ASCII就不丢失字符了。


不过BinaryToString()转一下为啥丢字符还是不清楚。

3mile 发表于 2012-3-9 10:48:52

$tBuffer = DllStructCreate("WCHAR[" & 512*$SecN & "]")

iPAQ 发表于 2012-3-9 11:16:34

本帖最后由 iPAQ 于 2012-3-9 12:06 编辑

谢谢3mile回复!

没看明白把byte换成wchar有何用意?
我发现只是数据由1个字节变成2个字节了。照样丢字符。是BinaryToString转换时丢的不是$tBuffer装不下丢的。和我这段程序出的问题好像不是一回事。

haijie1223 发表于 2012-3-9 11:20:14

学习了用这个方法能改写mbr不?

iPAQ 发表于 2012-3-9 11:27:02

用_WinAPI_ 打开 移动指针位置 等 能写MBR,用Autoit自己内置函数还没试成功。

3mile 发表于 2012-3-9 13:54:38

也许是我没有理解楼主的意思.

;十六进制字符串转ASCII测试
#INCLUDE <ARRAY.AU3>

$Hex="FFFEFDFCFBFA9998979695FFFF"
;~ $Hex=""
;~ For $i = 255 To 1 Step -1
;~         $Hex=$Hex & Hex($i,2)
;~ Next
;~ MsgBox(0,"10","<[" & $Hex & "]> len=" & StringLen($Hex) & @CRLF & "<[" & BinaryToString("0x" & $Hex,1) & "]> len=" & StringLen(BinaryToString("0x" & $Hex,1)) & @CRLF & "<[" & StringTrimLeft(Binary(BinaryToString("0x" & $Hex,1)),2) & "]> len=" & StringLen(StringTrimLeft(Binary(BinaryToString("0x" & $Hex,1)),2)))

Local $ARRAY
$ARRAY="原始数据:FFFEFDFCFBFA9998979695FFFF"
$ARRAY=$Hex
$ARRAY=Binary("0x"&$Hex)
$ARRAY=BinaryToString(Binary("0x"&$Hex))

$ARRAY="原始数据:FFFEFDFCFBFA9998979695FFFF"
$ARRAY="$Hex(字符形式)长度:"&StringLen($Hex)
$ARRAY="二进制长度:"&BinaryLen("0x"&$Hex)
$ARRAY="转字符串后长度:"&StringLen(BinaryToString(Binary("0x"&$Hex)))

$ARRAY="Wchar"
$ARRAY="Byte"

$Str=BinaryToString("0x" & $Hex,1)
;StringLen将每两个高位ASCII码当做中文字符计算个数。
$SecN=1
$tBuffer = DllStructCreate("wchar[" & 512*$SecN & "]")
DllStructSetData($tBuffer, 1, StringToBinary($Str))

$tBuffer1 = DllStructCreate("byte[" & 512*$SecN & "]")
DllStructSetData($tBuffer1, 1, $Str)

$ARRAY="数据结构大小: " & DllStructGetSize($tBuffer)
$ARRAY="数据结构指针: " & DllStructGetPtr($tBuffer)
$ARRAY="结构中数据:" & DllStructGetData($tBuffer, 1)
$ARRAY="结构中数据字符串:" & BinaryToString(DllStructGetData($tBuffer, 1))
$ARRAY="结构字串长度: " & StringLen(BinaryToString(DllStructGetData($tBuffer, 1)))

$ARRAY="数据结构大小: " & DllStructGetSize($tBuffer1)
$ARRAY="数据结构指针: " & DllStructGetPtr($tBuffer1)
$ARRAY="结构中数据:" & DllStructGetData($tBuffer1, 1)
$ARRAY="结构中数据字符串:" & BinaryToString(DllStructGetData($tBuffer1, 1))
$ARRAY="结构字串长度: " & StringLen(BinaryToString(DllStructGetData($tBuffer1, 1)))
_ArrayDisplay($ARRAY)
;然后用下面函数写入磁盘,这里为防误写磁盘注释掉
;_WinAPI_WriteFile($hDisk, DllStructGetPtr($tBuffer), 512*$SecN, $nBytes)

iPAQ 发表于 2012-3-9 21:17:29

本帖最后由 iPAQ 于 2012-3-9 21:25 编辑

感谢 3mile 具体详细的答复!

我比较笨,之前没明白你此处修改的用意。

执行了具体代码后看到wchar 和 byte 确实有区别。
但感觉造成转换时丢字符主要是 DllStructSetData($tBuffer, 1, StringToBinary($Str)) 和 DllStructSetData($tBuffer, 1, $Str) 这两句不同产生的。

再试发现:
Binary(BinaryToString("0x" & $Hex,1)) 丢字符
StringToBinary(BinaryToString("0x" & $Hex,1)) 不丢字符

一时脑筋还没转过来弯,让我慢慢想想差哪了。

再次谢谢答复!
页: [1]
查看完整版本: [已解决]在将十六进制字符串写磁盘时,用BinaryToString转换后丢失部分字符