首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将包含4字节编码的UTF-8编码文件读入Excel。

将包含4字节编码的UTF-8编码文件读入Excel。
EN

Stack Overflow用户
提问于 2017-10-19 20:19:33
回答 1查看 3.1K关注 0票数 2

读取UTF-8文件的推荐技术是:

代码语言:javascript
复制
  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,编码为多字节序列:

代码语言:javascript
复制
  -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”包含:

代码语言:javascript
复制
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(√)和年(年).例如,4字节编码是“闪闪发光的心脏”(H1F496)和“带微笑眼睛的笑脸”(H1F601)。

我找不到任何东西表明Office产品可以处理U+FFFF以上代码的字符。我怀疑当ReadText到达一个4字节的编码时,它会以一个没完没了的循环结束。

我有自己的VBA程序来解码UTF-8文件。当第一次遇到4字节编码时,它也无法处理它们。此后,我对我的例程进行了改进/更正,以接受4字节编码,并将它们解码为数字字符实体。例如,“笑脸带微笑的眼睛”(H1F601)作为HF0 9F 9881的文件载于文件中,我的例程将其解码为😁。如果将此数字字符实体放置在html文件中,Microsoft将显示正确的表情符号。我理解谷歌Chrome和大多数(全部?)现代浏览器也可以处理这样的数字字符实体。你能看到什么:😁?由于包含这些字符的文本是html,所以我的解决方案足以满足我当前的需求。

我将在几天后将我的例行公事作为回答,除非一个更好的答案是先发布的。人们是否同意ADODB的ReadText被4字节编码所击败?Office产品,特别是Excel能否处理平面1 Unicode字符(H10000到H1FFFF)?除了使用数字字符之外,还有别的选择吗?

更多的背景

我接受了汤姆·布洛杰特的回答,因为它确实回答了我的问题。然而,这不是我所希望的答案。

几年前,我收到了不同格式的文件,包括UTF-16、UTF-8、ASCII和ISO-8859-1。这些文件的作者从不同的应用程序中提取数据,但我发现各种格式出乎意料;在我的经验中,现在大多数应用程序都使用UTF-8。我的供应商都不知道他们的源应用程序创建了什么格式,也不知道如何将输出格式更改为UTF-8或其他一致的格式。

“传统VBA”将读取或写入ASCII或Unicode ( Microsoft的意思是OCS-2)文件。显然,接触网-2与UTF-16“几乎相同”。对我来说,“几乎相同”的意思是不同的,但我找不到任何东西来解释它们有何不同。ADODB是一个VBA库,它将接受其他格式,但所有文档都意味着您必须知道该格式是什么。像NotePad++这样的实用程序会打开任何文本文件并告诉您它的格式。我找不到和VBA类似的东西。

我决定必须编写自己的代码才能将每个文件读入一个字节数组并识别格式。识别格式并不比识别和转换到VBA字符串少得多,所以我就是这样做的。文件不是特别大,所以读取和转换所用的时间少于.01秒,这足以满足我的需要。

当我需要阅读“examples.json”时,我自然地使用了我的例行公事。我现在知道“examples.json”包含166个4字节编码,而我的例程没有正确处理它们。我修正了我例程中的错误,并对结果感到满意,除了处理92 my文件的最新版本花了34秒钟。我试过ADODB看看它有多快,但它从未终止。在我问这个问题之前,我已经走了这么远。

我读过ADODB不是很有效率,你应该一次读一个小块。然而,我并没有把“低效”等同于“不终止”,直到我尝试了Tom的回答。通过按照建议优化ADODB的使用,它现在终止了。研究输出提高了我对UTF-8编码的理解,所以这是一个有用的练习。然而,在大约40秒时,ADODB甚至比我的VBA例程慢。

在我的笔记本电脑上,以下代码在大约.1秒内将整个92 my文件读取到一个字节数组中:

代码语言:javascript
复制
  FileNum = FreeFile
  Open PathFileName For Binary Access Read As FileNum
  ReDim FileBodyByte(1 To LOF(FileNum))
  Get FileNum, , FileBodyByte
  Close FileNum

在字节数组中,对字符串的转换完全是处理器绑定的.为什么ADODB需要在128 K块中读取这个块?如果一个块在编码的中间结束,会发生什么情况?为什么要花这么长时间?我已经将处理器绑定的VBA例程转换为VB.Net,并将持续时间降低了1,000倍。使用ADODB是我向客户发布的例程,我会感到很不舒服。

微软似乎痴迷于向前兼容性。我15年前编写的VBA代码仍然有效。Microsoft没有增强旧例程;如果要提供新功能,它会引入新的库。ADODB很老了。我希望有新的,更好的,而不是一个解决办法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-20 00:19:12

ADODB.Stream.ReadText文档解释了一个效率问题,并建议一次读取更少的字节来减轻效率问题。

所以,

代码语言:javascript
复制
  Dim FileStream As Stream: Set FileStream = CreateObject("ADODB.Stream")

  With FileStream
    .Charset = "utf-8"
    .Open
    .LoadFromFile "C:\Users\Tom\Downloads\examples.json"

    Dim FileBodyADO As String: FileBodyADO = ""
    While Not .EOS
        FileBodyADO = FileBodyADO & .ReadText(128 * 1024&)
    Wend
    Debug.Print Len(FileBodyADO)
    Debug.Assert Len(FileBodyADO) = 92630322
    .Close
  End With

  Set FileStream = Nothing

正如.NET独立告诉您的,examples.json包含有92630322个代码单元的UTF-16编码的文本。(自1990年代初以来,VBA/VB4+使用了UTF-16字符串,其他许多语言也使用了UTF-16字符串。)

代码语言:javascript
复制
File.ReadAllText(@"C:\Users\Tom\Downloads\examples.json").Length == 92630322
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46838258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档