推薦的技術,用於讀取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個編碼單元就好了。這個問題似乎是別的,也許是文件大小。 –