用VBS读写二进制文件

标签: , , , ,

网上关于VBS读写二进制文件和二进制数据的文章很少,估计是高手们都很忙,那就由我这个菜鸟来写吧。不知道会不会被很多人复制粘贴然后还不注明出处,应该是会的。恩,我要好好学习知识产权法。

查了很多资料,很多不明真相的同学都叫嚣说用adodb.stream对象就可以实现。不错,是通过adodb.stream实现读写二进制文件的功能,问题是如何实现,你有自己测试过吗?给出的代码都是先用adodb.stream对象读取,然后又写入,这样做有什么意义,还不如直接复制。我想实现的是用adodb.stream直接写我保存在代码中的数据。我试过使用adodb.stream对象的write方法,但是每次都弹出"ADODB.Stream: Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another."错误。想到Linux之父Torvalds Linus的一句话:“Talk is cheap. Show me the code.”光说有什么用,把代码给出来啊。没有代码,就不要说话。

下面是读写二进制文件的两个函数(过程),并不是我写的,我没有那么高的水平,也没有那么厚的脸皮说是我写的,而是国外一位VBS高人写的,膜拜之。ReadBinary函数从文件读取二进制数据并返回数组,WriteBinary将数组中的数据以二进制的形式写到文件中。

Function ReadBinary(FileName)
  Dim Buf(), I
  With CreateObject("ADODB.Stream")
    .Mode = 3: .Type = 1: .Open: .LoadFromFile FileName
    ReDim Buf(.Size - 1)
    For I = 0 To .Size - 1: Buf(I) = AscB(.Read(1)): Next
    .Close
  End With
  ReadBinary = Buf
End Function

Sub WriteBinary(FileName, Buf)
  Dim I, aBuf, Size, bStream
  Size = UBound(Buf): ReDim aBuf(Size \ 2)
  For I = 0 To Size - 1 Step 2
      aBuf(I \ 2) = ChrW(Buf(I + 1) * 256 + Buf(I))
  Next
  If I = Size Then aBuf(I \ 2) = ChrW(Buf(I))
  aBuf=Join(aBuf, "")
  Set bStream = CreateObject("ADODB.Stream")
  bStream.Type = 1: bStream.Open
  With CreateObject("ADODB.Stream")
    .Type = 2 : .Open: .WriteText aBuf
    .Position = 2: .CopyTo bStream: .Close
  End With
  bStream.SaveToFile FileName, 2: bStream.Close
  Set bStream = Nothing
End Sub

非常的强大,我写了一个示例程序,用WriteBinary过程写了一张图片,感兴趣的可以下载来测试一下。

[download id=13]

随机文章:

  1. VBS For Next循环的一些细节
  2. VBScript的结束,Python的开始
  3. VBS调用WMI搜索文件
  4. 用VBS解析JSON格式数据之VbsJson类
  5. SDK编程中的窗口居中

12 条评论 发表在“用VBS读写二进制文件”上

  1. 蛮干的新手说道:

    您好,本人是高中化学教师,由于工作需要(辅助,以提高效率)外加喜欢就自学了一点asp,在asp中用vbs写了一些初级的东西来处理工作中的一些数据,呵呵,知道走了很多弯路,但苦于没人指引,而且总比人工强,就凑合用。在网上搜了一大圈,发现了您的博客,发现汝非凡人也!望能得到您的指点!
    最近在琢磨用vbs来处理二进制数据,不是简单的读取,而是进行一些数据运算(加减乘除),不知如何写有效的代码?我尝试了一下用下面的方法可以处理,但效率慢得让人窒息。
    set ados=Server.CreateObject(“ADODB.Stream”)
    ados.mode=3
    ados.type=1
    ados.open
    ados.loadFromFile server.mappath(files)
    str=ados.read()
    然后用ascB(midB(str,i,1))来获取指定字节所代表的数据进行相关运算。
    我想慢的原因是把字节数据当作了字符来对待,这样一旦二进制数据文件稍大(不到1M),就根本处理不了。我想问是否有直接获取二进制数据文件中的数据(格式化的,非常有规律)的方法?

    • Demon说道:

      我高中班主任也是化学老师,不过她不懂ASP。
      但是您为什么要用ASP呢,还要配置IIS,直接用VBS不是方便点?
      我学VBS也走了很多弯路,国内网站那些所谓的教程太烂,误人子弟。
      您说的没错,ascB(midB(str,i,1))慢的原因是把字节数据当作了字符来对待了,而这样直接处理字符串的效率是很低的。read方法是可以带参数的,您可以考虑用数组来实现,由于不知道您数据的格式,我也不能给出具体的解决方法,您可以通过QQ或GTalk与我交流。

      • 蛮干的新手说道:

        呵呵,有时候可以方便的以IE访问远程上的数据,加上数据共享。

      • 蛮干的新手说道:

        呵呵,用数组来处理也即用您上面的第一段代码来处理效率已经非常另我满意,问题已经解决,非常感谢!真是高人作品就是不一样!

  2. 蛮干的新手说道:

    刚才又看了您的“VBS和C语言效率比较”,发现您用的也是ascB(midB(str,i,1)),看来vb虽然简单,但是效率只能低下!可惜我不懂C语言!

    • Demon说道:

      VBS效率不高那是没法改变的,处理二进制数据更是超出了VBS的能力范围,这应该是C语言等“低级”语言来做的。

  3. playmessenge说道:

    這正是我要的,當初也寫了很久不知道錯在哪.感謝版大的分享.

  4. newpub说道:

    学习了,真的不错

  5. Jimmy_314说道:

    其实是我是一名vbs业余爱好者,当时用vbs是为了在做测试时省事,无非就是用几个sleep sendkeys,appactivate,run 就能搞定,但却后来却慢慢迷上了这东西,现在也基本能玩的转了,但发现要学的还很多啊,比如这个对象我就一点都不懂
    有时候,我想,vbs本身就是为了省事的,好多对象要学习使用很难,那为什么不自己写dll文件呢,dll 文件可以用c 和basic 写,vbs就只做简单的调用,也不用去学那些复杂的对象,其实我们大部分时间要处理的东西也东不会太复杂,学一些简单的vb,vc就可以写了

  6. crlf说道:

    处理奇数字节长度的时候会多输出一个 Null 字符,尝试切换代码页无果,请教下该如何避免呢?

留下回复