【问题标题】:Read and write binary file in VBscript在VBscript中读写二进制文件
【发布时间】:2011-05-19 14:49:33
【问题描述】:

我之前使用 ADODB.Stream 来读写二进制文件,这里是那个链接

How to concatenate binary file using ADODB.stream in VBscript

它工作正常,唯一的问题是 ADODB.stream 在 Windows 2003 服务器上被禁用,

有没有另一种方法我可以以二进制模式读取 3 个文件并将它们连接起来或将它们存储在 VBscript 中的一个文件中

谢谢你 日本人

【问题讨论】:

    标签: vbscript


    【解决方案1】:

    基于 Luc125 和 Alberto 的答案是 2 个经过重新设计和简化的函数:

    读取函数

    Function readBinary(strPath)
    
        Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
        Dim oFile: Set oFile = oFSO.GetFile(strPath)
    
        If IsNull(oFile) Then MsgBox("File not found: " & strPath) : Exit Function
    
        With oFile.OpenAsTextStream()
            readBinary = .Read(oFile.Size)
            .Close
        End With
    
    End Function
    

    写入函数

    Function writeBinary(strBinary, strPath)
    
        Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
    
        ' below lines pupose: checks that write access is possible!
        Dim oTxtStream
    
        On Error Resume Next
        Set oTxtStream = oFSO.createTextFile(strPath)
    
        If Err.number <> 0 Then MsgBox(Err.message) : Exit Function
        On Error GoTo 0
    
        Set oTxtStream = Nothing
        ' end check of write access
    
        With oFSO.createTextFile(strPath)
            .Write(strBinary)
            .Close
        End With
    
    End Function
    

    【讨论】:

    • 你需要这条线吗? Dim oTxtStream: Set oTxtStream = oFSO.createTextFile(strPath)
    • 该行是为了检查文件的写访问。如果删除它,在某些情况下脚本可能会崩溃。
    • 虽然这在某些时候有效,但通常是一种不好的做法。 FSO 设计用于标准文本流。此解决方法不是万无一失的,并且在某些环境中确实会失败。最好坚持使用 ADODB,这是一种为处理二进制流而设计的本机方法。没有额外的开销,无论如何它更有效。双赢。
    【解决方案2】:

    一年前我也遇到过类似的问题。我们知道 TextStream 对象用于 ANSI 或 Unicode 文本数据,而不是二进制数据;如果流是二进制的,他们的 .readAll() 方法会产生损坏的输出。但是有解决方法。将字符一个一个地读入一个数组可以正常工作。这应该允许您将二进制数据读入 VB 字符串,并将其写回磁盘。在进一步操作此类二进制字符串时,不要忘记某些操作可能会导致字符串损坏,因为它们仅用于文本。我总是在使用二进制字符串之前将它们转换为整数数组。

    Function readBinary(path)
    Dim a
    Dim fso
    Dim file
    Dim i
    Dim ts
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set file = fso.getFile(path)
    If isNull(file) Then
        MsgBox("File not found: " & path)
        Exit Function
    End If
    Set ts = file.OpenAsTextStream()
    a = makeArray(file.size)
    i = 0
    ' Do not replace the following block by readBinary = by ts.readAll(), it would result in broken output, because that method is not intended for binary data 
    While Not ts.atEndOfStream
        a(i) = ts.read(1)
    i = i + 1
    Wend
    ts.close
    readBinary = Join(a,"")
    End Function
    
    

    Sub writeBinary(bstr, path) Dim fso Dim ts Set fso = CreateObject("Scripting.FileSystemObject") On Error Resume Next Set ts = fso.createTextFile(path) If Err.number <> 0 Then MsgBox(Err.message) Exit Sub End If On Error GoTo 0 ts.Write(bstr) ts.Close End Sub

    Function makeArray(n) ' Small utility function Dim s s = Space(n) makeArray = Split(s," ") End Function

    【讨论】:

    • 这种变通方法不是一个好的做法。它不适用于所有代码页。你真的在这里处理一个边缘情况,我不会把它投入生产。
    【解决方案3】:

    ADODB 流对象是 VBScript 读取二进制流的唯一本机方法。如果 ADODB 被禁用,您将需要安装一些其他第三方组件来提供相同的功能。

    【讨论】:

    • 无需安装任何外部;仍然可以在没有 ADODB 的情况下完成;我总是在没有它的情况下读/写二进制文件
    • @Zimba FSO 无法可靠地处理二进制数据。它专为文本流而设计。 ADODB 是唯一设计用于处理二进制数据流的本机方法。
    • File & FileSystemObject 都可以处理二进制数据。问题是要求没有 ADODB 的“另一种方式”。我在 Win 10 上测试了音频、视频、图像、zip 档案和 pdf。您的方法仅适用于 ADODB,无需外部下载。
    【解决方案4】:

    可以一起读取所有字节:

    Set FS = CreateObject("Scripting.FileSystemObject")
    Set fil = FS.GetFile(filename)
    fpga = fil.OpenAsTextStream().Read(file.Size)
    

    【讨论】:

    • 你的意思是 Read(fil.Size)?
    • FSO 不能可靠地处理二进制数据。
    • @Nilpo:你怎么只对我的回答投了票?您做了哪些测试来提出索赔?
    • 已知 .read 和 .write 的行为取决于系统区域设置。它在使用 EN 语言环境的英语国家可靠地工作。在其他国家/地区,它不起作用。
    【解决方案5】:

    ADODB 流对象是 VBScript 读取二进制流的唯一本机方法

    Const TypeBinary = 1
    Const ForReading = 1, ForWriting = 2, ForAppending = 8
    
    Function readBytes(file)
    
         Dim inStream: Set inStream = WScript.CreateObject("ADODB.Stream") ' ADODB stream object used
    
         inStream.Open ' open with no arguments makes the stream an empty container 
         inStream.type= TypeBinary
         inStream.LoadFromFile(file)
         readBytes = inStream.Read()
    
    End Function
    
    Sub writeBytes(file, bytes)
    
        Dim binaryStream: Set binaryStream = CreateObject("ADODB.Stream")
    
        binaryStream.Type = TypeBinary
        binaryStream.Open 'Open the stream and write binary data
        binaryStream.Write bytes
        binaryStream.SaveToFile file, ForWriting 'Save binary data to disk
    
    End Sub
    

    【讨论】:

      【解决方案6】:

      读取 3 个文件并加入一个文件(不带 ADODB):

      Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
      If oFSO.FileExists("out.bin") Then oFSO.DeleteFile("out.bin")
      Dim outFile : Set outFile = oFSO.OpenTextFile("out.bin", 8, true)
      
      ' 3 input files to concatenate
      Dim oFS1 : Set oFS1 = oFSO.GetFile("in1.bin")
      Dim oFS2 : Set oFS2 = oFSO.GetFile("in2.bin")
      Dim oFS3 : Set oFS3 = oFSO.GetFile("in3.bin")
      
      Dim read1 : Set read1 = oFS1.OpenAsTextStream()
      Dim read2 : Set read2 = oFS2.OpenAsTextStream()
      Dim read3 : Set read3 = oFS3.OpenAsTextStream()
      
      Dim write1 : write1 = read1.Read(oFS1.Size)
      read1.Close
      outFile.write(write1)
      
      Dim write2 : write2 = read2.Read(oFS2.Size)
      read2.Close
      outFile.write(write2)
      
      Dim write3 : write3 = read3.Read(oFS3.Size)
      read3.Close
      outFile.write(write3)
      
      outFile.Close
      

      在 Win 10 上对音频、视频、图像、zip 存档和 pdf(二进制文件)进行了测试,用于二进制文件复制、编辑、拆分、加入、修补和(字节级)加密、编码和压缩。

      有关二进制文件修补,请参阅example (answer) here

      【讨论】:

      • 原生 FSO 对象的 OpenAsTextStream 方法不支持二进制流。它不能可靠地处理二进制文件。
      • @Nilpo:当然它支持二进制文件;我在 Win 10 上测试了音频、视频、图像、zip 档案和 pdf
      • 已知 .read 和 .write 的行为取决于系统区域设置。它在使用 EN 语言环境的英语国家可靠地工作。在其他国家/地区,它不起作用。
      • @david:fso 可以 "write binary files" 但文本字符串函数将不起作用,因为“空值截断字符串”,并且二进制数据包含字符串。问题涉及二进制文件(单字节 ASCII/ANSI 字符),fso 可以处理。多字节/unicode 代码页中缺少代码点会导致错误,这些代码点是为其他语言提供的字符扩展。
      • 一个“高级的、易于使用的界面”ADODB 是为这些语言环境的抽象和语言环境映射/检测而开发的(也可以用GetLocaleWMI 完成( VBS后发布))。 VBScript 被限制访问本地文件系统。
      猜你喜欢
      • 2012-01-26
      • 2018-07-26
      • 2016-06-14
      • 2021-06-03
      • 2012-07-12
      • 2019-04-20
      • 2019-09-18
      • 1970-01-01
      相关资源
      最近更新 更多