1. 程式人生 > >關於ASP中按指定編碼寫入讀取檔案

關於ASP中按指定編碼寫入讀取檔案

什麼是 UTF-8?

  首先 UCS 和 Unicode 只是分配整數給字元的編碼表. 現在存在好幾種將一串字元表示為一串位元組的方法. 最顯而易見的兩種方法是將 Unicode 文字儲存為 2 個 或 4 個位元組序列的串. 這兩種方法的正式名稱分別為 UCS-2 和 UCS-4. 除非另外指定, 否則大多數的位元組都是這樣的(Bigendian convention). 將一個 ASCII 或 Latin-1 的檔案轉換成 UCS-2 只需簡單地在每個 ASCII 位元組前插入 0x00. 如果要轉換成 UCS-4, 則必須在每個 ASCII 位元組前插入三個 0x00.
在 Unix 下使用 UCS-2 (或 UCS-4) 會導致非常嚴重的問題. 用這些編碼的字串會包含一些特殊的字元, 比如 ’/0’ 或 ’/’, 它們在 檔名和其他 C 庫函式引數裡都有特別的含義. 另外, 大多數使用 ASCII 檔案的 UNIX 下的工具, 如果不進行重大修改是無法讀取 16 位的字元的. 基於這些原因, 在檔名, 文字檔案, 環境變數等地方, UCS-2 不適合作為 Unicode 的外部編碼.
在 ISO 10646-1 Annex R 和 RFC 2279 裡定義的 UTF-8 編碼沒有這些問題. 它是在 Unix 風格的作業系統下使用 Unicode 的明顯的方法.
每一種語言的不同的編碼頁,增加了那些需要支援不同語言的軟體的複雜度。因而人們制定了一個世界標準,叫做unicode.Unicode為每個字元提 供了唯一的特定數值,不論在什麼平臺上、不論在什麼軟體中,也不論什麼語言。也就是說,它世界上使用的所有字元都列出來,並給每一個字元一個唯一特定數 值。
Unicode的最初目標,是用1個16位的編碼來為超過65000字元提供對映。但這還不夠,它不能覆蓋全部歷史上的文字,也不能解決 傳輸的問題 (implantation head-ache's),尤其在那些基於網路的應用中。已有的軟體必須做大量的工作來程式16位的資料。
因此,Unicode用一些基本的保留字元制定了三套編碼方式。它們分別是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字 符是以8位序列來編碼的,用一個或幾個位元組來表示一個字元。這種方式的最大好處,是UTF-8保留了ASCII字元的編碼做為它的一部分,例如,在UTF -8和ASCII中,“A”的編碼都是0x41.
UTF8並不算是一種電腦編碼,而是一種儲存和傳送的格式,如前所述,每個Unicode/UCS字元都以 2或4個bytes來儲存,看看以下的比較:
以"I am Chinese"為例
用ANSI儲存:12 Bytes
用Unicode/UCS2儲存:24 Bytes + 2 Bytes(header)
用UCS4儲存:48 Bytes + 4 Bytes(header)
以"我是中國人"為例
用ANSI儲存:10 Bytes
用Unicode/UCS2儲存:10 Bytes + 2 Bytes(header)
用UCS4儲存:20 Bytes + 4 Bytes(header)
由此可見直接以Unicode/UCS的原始形式來儲存是一種極大的浪費,而且也不利於網際網路的傳輸(中文稍為合算一點^_^)。
有見及此,Unicode/UCS的壓縮形式--UTF8出現了,套用官方網站的首句話『UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.』,由於UTF也適用於編碼UCS,故亦可稱為『UCS transformation formats (UTF)』

  UTF8是以8bits即1Bytes為編碼的最基本單位,當然也可以有基於16bits和32bits的形式,分別稱為UTF16和UTF32,但目前用得不多,而UTF8則被廣泛應用在檔案儲存和網路傳輸中。

---------------------------------------------------------------------------------
ASP解決UTF-8:
    兩種生成xml的方法:
FSO方法生成XML
<%'生成XML,但是FSO生成的是ASCII碼,是二進位制的,不支援UTF-8,亂碼!
Dim xpath
sql="select * From temp"
set rs=db.execute(sql)
xpath="data.xml"
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set fout = fso.CreateTextFile(Server.MapPath(xpath))
fout.WriteLine rs("temp")
fout.close
%>

ADODB.Stream方法生成XML
<%'生成XML,用ADODB.Stream,支援UTF-8
Dim xpath
sql="select * From temp"
set rs=db.execute(sql)
str=rs("temp")

Set objStream = Server.CreateObject("ADODB.Stream")
With objStream
.Open
.Charset = "utf-8"
.Position = objStream.Size
.WriteText=str
.SaveToFile server.mappath("kevin.xml"),2
.Close
End With
Set objStream = Nothing

rs.close
Set rs=Nothing
%>
----------------------------------------------------------------------------

ASP中操作UTF-8格式的檔案
注意:這裡說的ASP可不是ASP.net。
ASP由於是一種古老的語言,它的一些功能對UTF-8支援非常差。
比如,你想生成一個UTF-8格式的檔案,使用常用的 Scripting.FileSystemObject 物件就不行。

Scripting.FileSystemObject 物件建立檔案的函式,是下面方式:
FileSystemObject.CreateTextFile(filename[,overwrite[,unicode]])

其中的 unicode 屬性是這樣描述的:

可選項。Boolean 值指明是否以 Unicode 或 ASCII 檔案格式建立檔案。如果以 Unicode 檔案格式建立檔案,則該值為 True;如果以 ASCII 檔案格式建立檔案,則該值為 False。如果省略此部分,則假定建立 ASCII 檔案。

我們是無法用這個函式來建立UTF-8格式檔案的。
這時候,我們可以使用 ADODB.Stream 物件,使用方法見下面:

Set objStream = Server.CreateObject("ADODB.Stream")
With objStream
.Open
.Charset = "utf-8"
.Position = objStream.Size
.WriteText=str
.SaveToFile server.mappath("/sitemap.xml"),2
.Close
End With
Set objStream = Nothing

附:
ASCII 、Unicode 、 UTF-8 介紹:
ASCII 是一種字符集,包括大小寫的英文字母、數字、控制字元等,它用一個位元組表示,範圍是 0-127。
由於 ASCII 表示的字元非常有限,各個國家或者地區在此基礎上提出了自己的字符集,比如在中國應用非常廣泛的 GB2312,它為漢字提供了編碼,用兩個位元組表示。
這些字符集之間互不相容,相同的數字可能表示不同的字元,為資訊交流帶來了麻煩。
Unicode 是一種字符集,它將世界上的所有字元對映成一個唯一的數字(code point),比如字母 a 對應的數字 0x0041。目前 Unicode 還處於發展中,它所包容的字元越來越多。
在將 Unicode 表示的字元進行儲存時,還需要一定的編碼方式,比如 UCS-2,它用兩個位元組來表示 Unicode 編碼的字元。而 UTF-8 是 Unicode 字符集的另外一種編碼方式,它是變長度的,最多 6 個位元組,小於 127 的字元用一個位元組表示,與 ASCII 字符集的結果一樣,因而具有非常好的相容性,ASCII 編碼下的英語文字不需要修改就可以當作 UTF-8 編碼進行處理,應用非常廣泛。

UTF-8 and Unicode FAQ
http://www.linuxforum.net/books/UTF-8-Unicode.html

ADODB.Stream元件Charset屬性值
http://www.5iya.com/blog/post/adodb_stream_charset_value.asp

用ADODB.Stream代替FSO讀取文字檔案
http://www.99net.net/study/page/1025101521.htm

-----------------------------------------------------------------------------
關於UTF-8 和 其他文字相相容的解決方法

研究好多天了,也試過好多辦法了,總結出目前發現最好的方法:
先說一下基本的東西:
<%@ codepage=936%>簡體中文
<%@ codepage=950%>繁體中文
<%@ codepage=65001%>UTF-8

codepage指定了IIS按什麼編碼讀取傳遞過來的串串(表單提交,位址列傳遞等)。
出亂碼的原因也就是網站要整合的時候模組編碼不一樣引起的。
就像我的部落格一樣,整合的時候都會出這個問題,因為BLOG是Utf-8的,
近來很多網友都在為這個問題諮詢,我嘗試了很多種方法。
最方便的方法如下:
不要轉換任何模組網頁的編碼該utf-8的還是utf-8,該Gb22312的還是Gb2312
在Utf-8模組的包檔案(如conn.asp,但是要注意conn.asp必須是在第一行呼叫)最前面加上
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%Session.CodePage=65001%>
在GB2312模組的包檔案最前面加上
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<%Session.CodePage=936%>
其他編碼的類推。

'開啟檔案PublicFunction OpenFile(FileName AsString) AsBoolean'FileName:需要開啟的檔名If ADO_Stream IsNothingThenExitFunction

    Err.Number
=0OnErrorGoTo ferr

   
With ADO_Stream
        .Type
=1
        .Mode
=3
        .Open
        .LoadFromFile FileName
        .Position
=0
        .Type
=2
        .Charset
= IIf(Coding ="", "gb2312", Coding)
        FileBody
= .ReadText
        .Close
   
EndWith
    OpenFile
=TrueExitFunction
ferr:
    ErrInfo
= FileName &"開啟失敗!錯誤資訊:"& Err.Description
    Debug.Print ErrInfo
    Err.Number
=0End Function'儲存檔案PublicFunction SaveFile(FileName AsString, strFileBody AsString) AsBoolean'FileName:檔案儲存路徑名字
'
strFileBody:需要儲存的檔案內容If ADO_Stream IsNothingThenExitFunction
   
    Err.Number
=0OnErrorGoTo ferr

   
With ADO_Stream
        .Type
=2
        .Mode
=3
        .Charset
= IIf(Coding ="", "gb2312", Coding)
        .Open
        .WriteText strFileBody
        .SaveToFile FileName,
2EndWith
   
    SaveFile
=TrueExitFunction
ferr:
    ErrInfo
= FileName &"儲存失敗!錯誤資訊:"& Err.Description
    Debug.Print ErrInfo
    Err.Number
=0End Function