如何在VBScript中创建UTF-16文件?

Mel*_*uza 1 vbscript

我的系统是Window 10 English-US.我需要将一些不可打印的ASCII字符写入文本文件.因此,例如对于ASCII值为28,我想将\ u001Cw写入文件.在用Java编码时,我不需要做任何特殊的事情.以下是我在VBS中的代码

Dim objStream
Set objStream = CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 2
objStream.Position = 0
objStream.CharSet = "utf-16"

objStream.WriteText ChrW(28)  'Need this to appear as \u001Cw in the output file

objStream.SaveToFile "C:\temp\test.txt", 2
objStream.Close
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 5

您需要一个读写流,以便写入它并将其保存到文件中.

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"
Run Code Online (Sandbox Code Playgroud)

其他说明:

  • 我喜欢用Const代码中的所有常量显式定义.使阅读变得更加容易.
  • 一个With块在这里节省了一些打字.
  • 将流类型设置adTypeText为不是必需的,无论如何这都是默认值.但我猜,明确比隐含更好.
  • Position在新流上设置为0是多余的.
  • 不必使用ChrW()ASCII范围字符.将流Charset保存到文件时,流将决定字节宽度.在RAM中,无论如何都是Unicode(是的,甚至在VBScript中).
  • ADODB.Stream支持两种UTF-16编码:little-endian UTF-16LE(默认为同义词UTF-16)和big-endian UTF-16BE,字节顺序颠倒.

您可以使用FileSystemObject及其CreateTextFile()方法获得相同的结果:

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"
Run Code Online (Sandbox Code Playgroud)

这有点简单,但它只提供一个布尔Unicode参数,它在UTF-16和ANSI之间切换(不是ASCII,因为文档错误地声称!).该解决方案ADODB.Stream为您提供了细粒度的编码选择,例如UTF-8,这对于FileSystemObject来说是不可能的.


有关记录,有两种方法可以创建UTF-8编码的文本文件:

  • 微软喜欢这样做的方式,文件开头有一个3字节长的字节顺序标记(BOM).大多数(如果不是全部)Microsoft工具在提供"UTF-8"选项时都这样做,ADODB.Stream也不例外.
  • 其他人的方式 - 没有BOM.这对大多数用途都是正确的.

要使用BOM创建UTF-8文件,可以使用上面的第一个代码示例.要创建没有 BOM 的UTF-8文件,我们可以使用两个流对象:

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
Run Code Online (Sandbox Code Playgroud)