推荐的技术,用于读取UTF-8的文件是:读UTF-8编码的文件,其中包括4字节编码到Excel
Dim FileStream As Stream
Dim FileBodyADO As String
Set FileStream = CreateObject("ADODB.Stream")
With FileStream
.Charset = "utf-8"
.Open
.LoadFromFile ("C:\DataArea\Resources\VBA Outlook\Tutorial\examples.json")
FileBodyADO = .ReadText()
.Close
End With
Set FileStream = Nothing
然而,如果你试图读取“examples.json”,这是部分的存档的SO文档,陈述FileBodyADO = .ReadText()
永远不会结束。
的UTF-8文件是一个字节定向文件(不同的是,例如,UTF-16),字符,其代码是在范围为0〜& H7F进行不变,并与编码以多字节以上& H7F码字符序列:
-Code (Hex)- ---------------Encoding---------------
Start End Byte 1 Byte 2 Byte 3 Byte 4
0 7F 0xxxxxxx
80 7FF 110xxxxx 10xxxxxx
800 FFFF 1110xxxx 10xxxxxx 10xxxxxx
10000 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
“examples.json”包含:
92,601,220 1-byte encodings
8,848 2-byte encodings
20,122 3-byte encodings and
166 4-byte encodings.
1字节的编码是ASCII字符。例如,2字节编码是§(HA7)和I(H131)。例如,3字节编码是√(H221A)和年(H5E74)。例如,4字节编码是“Sparkling Heart”(H1F496)和“笑脸笑脸”(H1F601)。
我找不到任何建议Office产品可以处理U + FFFF以上代码的字符。我怀疑ReadText
在遇到4字节编码时会以无限循环结束。
我有我自己的VBA例程来解码UTF-8文件。它们在第一次遇到时也无法处理4字节编码。自从我增强/纠正了我的例程以接受4字节编码并将它们解码为数字字符实体。例如,“笑脸笑脸”(H1F601)作为HF0 9F 98 81在文件中携带,我的例程解码为😁
。如果此数字字符实体放置在html文件中,则Microsoft Edge将显示正确的表情符号。我了解谷歌浏览器和大多数(所有?)现代浏览器也可以处理这种数字字符实体。你能看到什么:😁?由于包含这些字符的文本是html,因此我的解决方案足以满足当前的要求。
我会在几天内发布我的例程作为答案,除非先发布更好的答案。人们是否同意ADODB的ReadText
被4字节编码击败? Office产品,特别是Excel可以处理Plane 1 Unicode字符(H10000至H1FFFF)吗?我有使用数字字符的替代方法吗?
更多的背景
我已经接受了来自汤姆·布洛杰特的答案,因为它不回答我的问题。但是,这不是我希望的答案。
几年前,我收到了包含UTF-16,UTF-8,ASCII和ISO-8859-1的不同格式的文件。这些文件的作者从不同的应用程序中提取数据,但我发现各种格式都是意想不到的;根据我的经验,现在大多数应用程序都使用UTF-8。我的供应商都不知道他们的源应用程序创建了什么格式,或者如何将输出格式更改为UTF-8或其他一致。
“传统VBA”将读取或写入ASCII或Unicode(Microsoft表示OCS-2)文件。显然,OCS-2与UTF-16“几乎相同”。对我而言,“几乎相同”意味着不同,但我无法解释它们的不同之处。 ADODB是一个可以接受其他格式的VBA库,但所有文档都意味着您必须知道该格式是什么。像NotePad ++这样的工具将打开任何文本文件并告诉你它的格式。我无法找到与VBA相似的东西。
我决定写我自己的代码,将每个文件读入一个字节数组并确定格式。识别格式并不是很少能够识别和转换为VBA字符串,这就是我所做的。这些文件不是特别大,所以读取和转换时间少于0.01秒,这足以满足我的需求。
当我需要阅读“examples.json”时,我自然使用了我的例程。我现在知道“examples.json”包含166个4字节的编码,而且我的例程没有正确处理它们。我修复了我的例程中的错误,并对结果感到满意,除了用最新版本处理92Mb文件需要34秒。我尝试了ADODB,看看它有多快,但它永远不会终止。在我问这个问题之前,这是我得到的。
我读过ADODB不是很有效,你应该一次读一小块。然而,在我尝试Tom Blodget的答案之前,我并没有把“低效率”等同于“不终止”。按照建议通过优化ADODB的使用,它现在终止。研究输出增加了我对UTF-8编码的理解,所以这是一个有用的练习。然而,在大约40秒钟,ADODB甚至比我的VBA例程慢。
在我的笔记本电脑,下面的代码读取整个92MB文件到一个字节数组中约0.1秒时:
FileNum = FreeFile
Open PathFileName For Binary Access Read As FileNum
ReDim FileBodyByte(1 To LOF(FileNum))
Get FileNum, , FileBodyByte
Close FileNum
字节数组
一旦,转换为字符串是完全受处理器限制。为什么ADODB需要在128K块中读取块?如果块在编码中间结束会发生什么?为什么需要这么长时间?我已将处理器绑定的VBA例程转换为VB.Net,并将持续时间缩短了1,000倍。我不觉得舒服,使用ADODB是我发布给客户的例程。
微软似乎痴迷于向前兼容性。我15年前写的VBA代码仍然有效。微软并没有增强老套路。如果要提供新的功能,它会引入新的库。 ADODB是旧的。我希望有新的更好的东西,而不是解决方法。
否,ADODB.Stream处理UTF-8编码的字符与4个编码单元就好了。这个问题似乎是别的,也许是文件大小。 –