VB6 - FileSystemObject Write Error : “invalid procedure call or argument”


VB6 中使用以下方式讀取一個 UTF-8 文件後,另存爲一個新文件時出錯 “invalid procedure call or argument

‘ 讀取

     Dim adoS As Object
     Set adoS = CreateObject("adodb.stream")
     With adoS
         .Charset = "utf-8"
         .Type = 2
         .Open
         .LoadFromFile sUTF8File
         ReadUTF8 = .ReadText
         .Close
     End With


’ 另存文件

    Dim fso As New FileSystemObject
    Dim txtFile As TextStream
    
    Set txtFile = fso.CreateTextFile(sFile, True)
    txtFile.Write (strContent)
    txtFile.Close

一個臨時解決方法:

1,  txt中的內容Copy Word

2, Word中所有所有文字,使用轉半角功能(Aa 圖標下: Change Case \ Half-width),對文字進行半角轉換

3, 再從Word文件中將轉換後的文字Copy至原 txt 文件中,保存

 再次上傳即可成功


 另一個解決方法:

不使用另存文件,而直接使用讀取到的 String ,將字串轉爲數據,然後再對數據進行處理。


 Dim oarrLine() As String

    oarrLine = Split(ReadUTF8, vbCrLf)


真正的原因:

爲何會出錯,真正的原因可能是因爲文件內容有一些特別的字符,導致寫文件時錯誤。如下示例:


https://stackoverflow.com/questions/17094281/getting-invalid-procedure-call-or-argument-in-vbscript

用如下解決方法:

>> f.close
>> Set f = goFS.CreateTextFile(".\tmp.txt", True, True) ' overwrite, unicode
>> f.WriteLine ChrW(&H1F00)
>>
>> --- no news are good news --
但出來的文件變爲了一個 unicode 文件,而非 UTF-8 文件。

如直接使用 unicode 方式進行處理,後續會發現其中一些中文會亂碼,導致保存至DB後,數據不正確。


最後的發現:

最終確實使用Notepad++ 的Encoding \ Convert to ANSI 後,即可發現有些原爲空格的位置,變爲了問題"?" 或亂碼,將此類記錄處理後,即可正常處理了。


最後的最後:

歸根結底,還是VB6 的 CreateTextFile 及 File.write 方法太舊,太過時,無法處理新的特殊字符,還是要升級使用 .Net 的處理方法才能從根本上解決問題,而不再擔心用戶的輸入。


補充:

UTF-8轉GBK的悲劇:特殊字符C2A0

這個問題出現得比較早:在傳給印象派的作品描述XML(GBK編碼)中一些文字信息經常包含亂碼,而且會一亂到底,甚至導致不同頁的錯亂。剛開始一直都沒有什麼頭緒,不過後來終於發現了部分頭緒:GBK的字符集過小,對一些特殊字符的轉碼會出現亂碼—-一些生僻字也就算了,但是其中卻包括這個字符:C2A0—-一個在網頁上經常使用排版用全角空格。就是這麼個字符,用戶從網頁端拷貝了一段文字,複製到界面上顯示正常,保存到作品XML文件中(UTF8編碼),顯示正常。但是上傳作品時由於將相應的XML編碼格式轉換成GBK,於是出現了亂碼……
處理方法:

方法一:轉換時對文本信息做特殊處理,用0×20代替掉0xC2A0。

方法二:作品XML文件直接以UTF8編碼傳輸。

方法一有點頭疼治頭腳疼治腳的味道,雖然解決了這個問題,但是總歸不夠規範不夠完美—-很多頁面都是這麼做。而方法二則需要服務器支持,但可以完美的解決這個問題。以前服務器之所以用GBK編碼很大的理由可能在於GBK相對UTF8更省空間—-在這麼個硬盤空間足夠,帶寬足夠的現狀下,節約出來的那麼點東西又有什麼用呢?

[java] view plain copy
  1. /** 
  2.      *  
  3.      * 將不換行空格(NO-BREAK SPACE,Unicode 0x00a0,UTF-8編碼:0xC2A0)替換爲普通空格。 
  4.      *  
  5.      * 用於避免因數據庫字符集不兼容導致這個字符變爲問號“?”的情況。 
  6.      */  
  7.   
  8.     public static String nobreakSpaceToSpace(String str) {  
  9.         if (str == null) {  
  10.             return null;  
  11.         }  
  12.         char nbsp = 0x00a0;  
  13.         return str.replace(nbsp, ' ');  
  14.     }  




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章