用VBS读写二进制文件的另一种方法

标签: , , , ,

之前写的那篇给出的方法虽然不错,但是当文件过大时(其实很小,也就几M),对应的数组也会很大,然后会出现运行时错误,提示内存耗尽,为此我郁闷了好久。

最近在博客的流量记录中发现百度关键字“一些很恶作剧的vbs程序”(看来现在的年轻人很喜欢玩这口),于是打开久违的百度搜索了一下,发现出现在第三。出现在第二的是百度HI,上面也是一个恶作剧程序,而且还是加密的。我尝试着解密,却发现这个加密似乎比前几天解密的那个病毒更变态,未果。

虽然我没有把那个程序解密出来(如果哪位真正的高手会,麻烦指点一下),但是从中领悟出了用VBS读写二进制文件的另一种方法,即Microsoft.XMLDOM+ADODB.Stream。这个方法的效率比原来那个高得多,而且似乎没有文件大小限制。

Function ReadBinary(FileName)
	Const adTypeBinary = 1
	Dim stream, xmldom, node
	Set xmldom = CreateObject("Microsoft.XMLDOM")
	Set node = xmldom.CreateElement("binary")
	node.DataType = "bin.hex"
	Set stream = CreateObject("ADODB.Stream")
	stream.Type = adTypeBinary
	stream.Open
	stream.LoadFromFile FileName
	node.NodeTypedValue = stream.Read
	stream.Close
	Set stream = Nothing
	ReadBinary = node.Text
	Set node = Nothing
	Set xmldom = Nothing
End Function

函数的参数是要读取的文件路径,返回值是包含二进制文件的十六进制值的字符串。

Sub WriteBinary(FileName, Buf)
	Const adTypeBinary = 1
	Const adSaveCreateOverWrite = 2
	Dim stream, xmldom, node
	Set xmldom = CreateObject("Microsoft.XMLDOM")
	Set node = xmldom.CreateElement("binary")
	node.DataType = "bin.hex"
	node.Text = Buf
	Set stream = CreateObject("ADODB.Stream")
	stream.Type = adTypeBinary
	stream.Open
	stream.write node.NodeTypedValue
	stream.saveToFile FileName, adSaveCreateOverWrite
	stream.Close
	Set stream = Nothing
	Set node = Nothing
	Set xmldom = Nothing
End Sub

第一个参数是要读入的文件路径,第二个参数是包含二进制文件的十六进制值的字符串。至于如何获得二进制文件的十六进制值,那方法就很多了,最简单的方法当然就是用fso对象将ReadBinary函数的返回值写到文本文件中去,然后Ctrl+C,Ctrl+V。其实用十六进制工具也很简单。

其他的就不多说了,看不懂的多看看MSDN参考文档。写了一个示例程序,里面包含了天空之城音乐的所有数据,双击后在同一文件夹生成天空之城的MP3文件并播放。

[download id=29]

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. 自甘堕落
  2. VBS实现“多线程”
  3. 用VBS实现PHP的sha1_file函数
  4. 用C语言实现IBindStatusCallback接口
  5. OpenWrt搭建KMS服务器激活Windows和Office

32 条评论 发表在“用VBS读写二进制文件的另一种方法”上

  1. 小白说道:

    demon博主你好,如果我只想读取这个二进制文件的开头10个字符,请问要怎么写呢?我还是个vbs新手,能不能请你抽出一点时间,指导一下我,谢谢。

    • Demon说道:

      二进制文件是以字节为单位的,而不是字符
      如果你想读取前10个字节,可以用下面的代码
      Set ado = CreateObject(“Adodb.Stream”)
      ado.Type = 1
      ado.Open
      ado.LoadFromFile “data.bin”
      arr = ado.Read(10)

      • 小白说道:

        太谢谢您了,这个博客挺不错的,很简洁,很喜欢这种风格,祝您能写出更多更好的技术文章,我可是订阅了rss了呢Y(^_^)Y

  2. donpps说道:

    demon博主您好,请教:读取第19个字节开始的200个字节呢,怎么操作呢。
    我的想法是,读取A文件(二进制)的第19个字节开始的200个字节,经过一番变换,添加到B文件(二进制)的最后。先谢谢啦。

    • Demon说道:

      Set ado = CreateObject(“Adodb.Stream”)
      ado.Type = 1
      ado.Open
      ado.LoadFromFile “data.bin”
      ado.Position = 18 ‘定位到第19个字节
      arr = ado.Read(200) ‘读取200个字节

      • donpps说道:

        真的是太谢谢了,没想到博主这么勤奋乐于助人。这个东西应该是有指针的,不知道怎么写哦,中文的帮助太少啦。谢谢!

      • donpps说道:

        真的是太谢谢了,没想到博主这么勤奋乐于助人。这个东西应该是有指针的,不知道怎么写哦,中文的帮助太少啦。谢谢!

        • Demon说道:

          什么指针……

          • donpps说道:

            指针应该加上引号,就是Position位置。
            在操作一个136M的文件时,还是出现问题:
            Line :54
            Column:2
            Error:Not enough storage is available to complete this operation.
            Code:8007000E
            Source:msxml3.dll
            system:存储空间不足,无法完成此操作。
            必须分段操作,就是每次写入10M左右。如果没有好的方法,看样子只有走其它的路了。

  3. Vaxhall说道:

    有个小错误:node.NodeTypeValue 应该是 node.NodeTypedValue

  4. milkyalien说道:

    楼主,你好
    函数的参数是要读取的文件路径,返回值是包含二进制文件的十六进制值的字符串。
    这个返回值怎么获取,怎么用fso对象将ReadBinary函数的返回值写到文本文件中?
    先谢谢了!

  5. playmessenge说道:

    感謝版主分享,我蠻需要這程式
    題外話,想問版主除了DynamicWrapper外,有沒有辦法用vbs控制滑鼠.

  6. newpub说道:

    太强大了,受用

  7. newpub说道:

    太强大了,真的很受用

  8. 龙六刀说道:

    先下载了再研究!

  9. yxhhs说道:

    很受用!研究研究

  10. yxhhs说道:

    能不能分批分批读取二进制文件,读一次指针怎么下移?

donpps 留下回复