Content
是包含Unicode字符的流。这些可以是UTF-8,UTF-16或UTF-32,并且两种字节序都可以。
这是一个具有UTF-16 Unicode字符的实例,其中包括一个表示Little Endian的BOM:FF FE
。
我在此文件中有一张职位表。这些位置以16位字符表示。 BOM位于位置0,即BOM位置之后的2个字节。
这样做的时候
Dim oContent = New StreamReader(Content, Text.Encoding.Unicode)
Dim sContent = oContent.ReadToEnd
物料清单被完全吞没:
?scontent
"AAaa" & vbCrLf & "BB111" & vbCrLf & "BB22222" & vbCrLf & "CCc" & vbCrLf & ...
将detectEncodingFromByteOrderMarks
设置为False
时:
Dim oContent = New StreamReader(Content, False)
Dim sContent = oContent.ReadToEnd
每个字符代表一个字节(但包括BOM):
?scontent
"��A" & vbNullChar & "A" & vbNullChar & "a" & vbNullChar & "a" & vbNullChar & vbCr & vbNullChar & vbLf & ...
两者的结合
Dim oContent = New StreamReader(Content, Text.Encoding.Unicode, False)
Dim sContent = oContent.ReadToEnd
再次完全吞下BOM:
?scontent
"AAaa" & vbCrLf & "BB111" & vbCrLf & "BB22222" & vbCrLf & "CCc" & vbCrLf & "DDddd" & vbCrLf
问题:我可以以某种方式在字符串中获取以下内容,就像在流中一样吗?
Char 0 1 2 3
Byte 0 1 2 3 4 5 6 7
Content FF FE 41 00 41 00 61 00 ...
String.Substring(1,3)应该产生“ AAa”
如果不是::我能以某种方式检测到提供了什么BOM和多少字节吗? (输入文件之间有所不同。)
答案 0 :(得分:1)
我能以某种方式检测到提供了什么BOM和多少字节吗?
如果您的文件(或流,无论如何)是UTF-16编码的,则BOM始终为2个字节:FE FF
或FF FE
。
因此,如果您确实需要了解BOM(如果文件是大端或小端),则只需读取文件(或流)的前两个字节即可:
Dim data as Byte()
Using fs = File.OpenRead("path/to/file/test.txt")
Using binaryReader = new BinaryReader(fs)
data = binaryReader.ReadBytes(2)
End Using
End Using
如果您的文件包含BOM表,data
现在将包含FE FF
或FF FE
。
但是您还说过,您已经知道您的文件是UTF-16 little-endian文件,因此对我来说您实际上想实现的目标还不清楚。
当您将文件/流读取为字符串时,该字符串将不包含BOM,因为这没有意义:BOM不是实际内容的一部分,它只是指示如何解释内容的标记。一堆字节。
还要注意,并非UTF-16字符串中的每个字符都由两个8位字节表示:字符也可以由4个字节表示。
如果要将内容作为字符串,只需使用StreamReader(Content, Text.Encoding.Unicode)
。
以您的示例
String.Substring(1, 3)
应该产生"AAa"
要么从索引(1
中减去String.Substring(0, 3)
,要么在字符串(Dim sContent = "x" + oContent.ReadToEnd
)中添加一个虚拟的16位字符。
更新:要获取文件/流的编码,请让StreamReader
为您完成工作:
Dim encoding as Encoding
using sr = new StreamReader(filename, true)
sr.peek()
encoding = sr.CurrentEncoding
end using
encoding.BodyName
现在是utf-16BE
。