How to create UTF-16 file in VBScript?

后端 未结 1 1634
失恋的感觉
失恋的感觉 2021-01-24 00:16

My system is Window 10 English-US. I need to write some non-printable ASCII characters to a text file. So for eg for the ASCII value of 28, I want to write \\u001Cw to the file.

相关标签:
1条回答
  • 2021-01-24 00:53

    You need a read-write stream so that writing to it and saving it to file both work.

    Const adModeReadWrite = 3
    Const adTypeText = 2
    Const adSaveCreateOverWrite = 2
    
    Sub SaveToFile(text, filename)
      With CreateObject("ADODB.Stream")
        .Mode = adModeReadWrite
        .Type = adTypeText
        .Charset = "UTF-16"
        .Open
        .WriteText text
        .SaveToFile filename, adSaveCreateOverWrite
        .Close
      End With
    End Sub
    
    
    text = Chr(28) & "Hello" & Chr(28)
    SaveToFile text, "C:\temp\test.txt"
    

    Other notes:

    • I like to explicitly define with Const all the constants in the code. Makes reading so much easier.
    • A With block save quite some typing here.
    • Setting the stream type to adTypeText is not really necessary, that's the default anyway. But explicit is better than implicit, I guess.
    • Setting the Position to 0 on a new stream is superfluous.
    • It's unnecessary to use ChrW() for ASCII-range characters. The stream's Charset decides the byte width when you save the stream to file. In RAM, everything is Unicode anyway (yes, even in VBScript).
    • There are two UTF-16 encodings supported by ADODB.Stream: little-endian UTF-16LE (which is the default and synonymous with UTF-16) and big-endian UTF-16BE, with the byte order reversed.

    You can achieve the same result with the FileSystemObject and its CreateTextFile() method:

    Set FSO = CreateObject("Scripting.FileSystemObject")
    
    Sub SaveToFile(text, filename)
      ' CreateTextFile(filename [, Overwrite [, Unicode]])
      With FSO.CreateTextFile(filename, True, True)
        .Write text
        .Close
      End With
    End Sub
    
    
    text = Chr(28) & "Hello" & Chr(28)
    SaveToFile text, "C:\temp\test.txt"
    

    This is a little bit simpler, but it only offers a Boolean Unicode parameter, which switches between UTF-16 and ANSI (not ASCII, as the documentation incorrectly claims!). The solution with ADODB.Stream gives you fine-grained encoding choices, for example UTF-8, which is impossible with the FileSystemObject.


    For the record, there are two ways to create an UTF-8-encoded text file:

    • The way Microsoft likes to do it, with a 3-byte long Byte Order Mark (BOM) at the start of the file. Most, if not all Microsoft tools do that when they offer "UTF-8" as an option, ADODB.Stream is no exception.
    • The way everyone else does it - without a BOM. This is correct for most uses.

    To create an UTF-8 file with BOM, the first code sample above can be used. To create an UTF-8 file without BOM, we can use two stream objects:

    Const adModeReadWrite = 3
    Const adTypeBinary = 1
    Const adTypeText = 2
    Const adSaveCreateOverWrite = 2
    
    Sub SaveToFile(text, filename)
      Dim iStr: Set iStr = CreateObject("ADODB.Stream")
      Dim oStr: Set oStr = CreateObject("ADODB.Stream")
    
      ' one stream for converting the text to UTF-8 bytes
      iStr.Mode = adModeReadWrite
      iStr.Type = adTypeText
      iStr.Charset = "UTF-8"
      iStr.Open
      iStr.WriteText text
    
      ' one steam to write bytes to a file
      oStr.Mode = adModeReadWrite
      oStr.Type = adTypeBinary
      oStr.Open
    
      ' switch first stream to binary mode and skip UTF-8 BOM
      iStr.Position = 0
      iStr.Type = adTypeBinary
      iStr.Position = 3
    
      ' write remaining bytes to file and clean up
      oStr.Write iStr.Read
      oStr.SaveToFile filename, adSaveCreateOverWrite
      oStr.Close
      iStr.Close
    End Sub
    
    0 讨论(0)
提交回复
热议问题