|
|
|
|
|
今天用VB生成XML文件,生成后再用VB打開(kāi)時(shí)提示有不可用的字符,由于此程序已經(jīng)測(cè)試過(guò)打開(kāi)XML文件是沒(méi)有問(wèn)題的,我再仔細(xì)檢查一下生成的XML文件,并沒(méi)發(fā)現(xiàn)有非法字符或格式錯(cuò)誤的問(wèn)題,于是我就想到可能是編碼的問(wèn)題。
檢查方法很簡(jiǎn)單,用文本方式打開(kāi)XML文件,然后“另存為...”,看到顯示什么編碼,文件就是什么編碼。
經(jīng)檢查,生成的XML文件是ANSI編碼。
而程序能成功打開(kāi)的XML文件是UTF-8編碼。
所以,我要實(shí)現(xiàn)VB生成UTF-8編碼的XML文件。
網(wǎng)上找了一會(huì),終于找到了親測(cè)有效的代碼。
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" ( _
ByVal CodePage As Long, _
ByVal dwFlags As Long, _
ByVal lpWideCharStr As Long, _
ByVal cchWideChar As Long, _
ByVal lpMultiByteStr As Long, _
ByVal cbMultiByte As Long, _
ByVal lpDefaultChar As Long, _
ByVal lpUsedDefaultChar As Long) As Long
Private Sub getUtf8(ByRef s As String, ByRef b() As Byte)
Const CP_UTF8 As Long = 65001
Dim len_s As Long
Dim ptr_s As Long
Dim size As Long
Erase b
len_s = Len(s)
If len_s = 0 Then _
Err.Raise 30030, , "Len(WideChars) = 0"
ptr_s = StrPtr(s)
size = WideCharToMultiByte(CP_UTF8, 0, ptr_s, len_s, 0, 0, 0, 0)
If size = 0 Then _
Err.Raise 30030, , "WideCharToMultiByte() = 0"
ReDim b(0 To size - 1)
If WideCharToMultiByte(CP_UTF8, 0, ptr_s, len_s, VarPtr(b(0)), size, 0, 0) = 0 Then _
Err.Raise 30030, , "WideCharToMultiByte(" & Format$(size) & ") = 0"
End Sub
Public Sub writeUtf()
Dim file As Integer
Dim s As String
Dim b() As Byte
s = "äöüßµ@€|~{}[]²³\ .." & _
" OMEGA" & ChrW$(937) & ", SIGMA" & ChrW$(931) & _
", alpha" & ChrW$(945) & ", beta" & ChrW$(946) & ", pi" & ChrW$(960) & vbCrLf
file = FreeFile
Open "C:\Temp\TestUtf8.txt" For Binary Access Write Lock Read Write As #file
getUtf8 s, b
Put #file, , b
Close #file
End Sub
代碼比較復(fù)雜,沒(méi)有一定VBA基礎(chǔ)是難以讀懂理解的,大概是通過(guò)二進(jìn)制訪問(wèn)字符串字節(jié)并轉(zhuǎn)換成UTF-8的編碼格式。
現(xiàn)在很少人用VB編寫應(yīng)用程序了,工作效率太低,如本文的例子,用C#或VB.NET,幾行代碼就搞定了,因?yàn)楹芏嗪瘮?shù)都封裝好了,功能齊全,用它們來(lái)編寫應(yīng)用程序,效率高很多。
不過(guò)用VB編寫的應(yīng)用程序,由于用的都是底層的東西,拿到另一平臺(tái)運(yùn)行,不需要安裝什么框架,很方便,我覺(jué)得這是它的一大優(yōu)點(diǎn)。