官术网_书友最值得收藏!

2.3.2 文本數據

1. 寫入文本數據

處理方式為文本時,即Type屬性為2時,寫入數據使用WriteText方法,如:

stream.WriteText "哈哈"

如果要寫入行分隔符,可以這樣:

stream.WriteText "哈哈" & vbCrLf

實際上,可以更簡單一些:

stream.WriteText "哈哈",1

這里使用了WriteText方法的第二個參數,它的可選值是0和1,默認是0,只寫數據,如果是1的話,則寫入數據之后,會再寫入一個行分隔符。

行分隔符默認的就是vbCrLf,可以通過Stream對象的LineSeparator屬性來修改它,它的可選值如表2-8所示。

表2-8 行分隔符的可選值

2. 讀取文本數據

處理方式為文本時,讀取數據使用ReadText方法,它只有一個參數,是要讀取字符的個數。注意是字符個數,不是字節數。如果參數省略,則從當前位置一直讀到數據流的末尾。

該參數還有兩個特殊值,-1和-2。前者的作用與省略參數一樣,后者則表示讀取一行數據。如果指針位于一行的中間,則從當前位置讀到行分隔符之前。如果想跳過一行不讀取,可以使用SkipLine方法。

看一下范例。

TextWriteAndRead.asp

<%
Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 2                     '文本方式
stream.Charset = "GBK"
stream.Open

'寫入數據
stream.WriteText "哈哈",1           '寫入行分隔符
stream.WriteText "Hello World" & vbCrLf
stream.WriteText "你好"

'讀取所有文本
stream.Position=0
response.write "<textarea rows='5' cols='20'>"
response.write stream.ReadText
response.write "</textarea>"

'讀取文本
stream.Position=0
stream.SkipLine                     '跳過第一行
response.write "<textarea rows='3' cols='20'>"
response.write stream.ReadText(-2)   '讀取一行
response.write stream.ReadText(-2)   '讀取一行
response.write "</textarea>"

stream.close
Set stream = nothing
%>

運行結果如圖2-13所示。

為了看出換行符的作用,這里使用了<textarea>文本框來顯示文字。右邊文本框中的“Hello World”和“你好”是顯示在一行的,說明使用參數-2讀取的一行文字是不包含行分隔符的。

圖2-13 文本數據寫入與讀取

3. 指針的移動

指針就是指向當前位置的一個東西,它指向哪里,哪里就是開始處理的位置。使用Position屬性可以得到指針當前的位置,如果指針位于數據流的開頭位置,則Position屬性為0。

我們來看一下指針移動的示意圖,如圖2-14所示。

圖2-14 指針移動的示意圖

從圖2-14可以看出,伴隨著數據的讀寫操作,指針一直在移動。所以,讀取數據之前要留意一下指針的位置,必要時,先把它移動到正確的位置,再讀取數據。

處理形式為二進制時,指針的移動也是類似的。

4. Charset的作用

處理方式為文本時,可以通過Charset屬性指定文本的字符集,不指定則默認的是Unicode。處理方式為二進制時,不要使用Charset屬性,會報錯。變更Charset,要求指針必須指向位置0,其他位置該屬性是只讀的。

為了理解Charset的作用,我們做一個簡單的試驗。

首先,先看一下getMemoryFormat方法,它的功能是取得二進制數據的字符串表示形式,后面的例子中將省略它。

Function getMemoryFormat(bstr)
    Dim result, i
    For i=1 To Lenb(bstr)
            numberHex = Hex(AscB(MidB(bstr, i,1)))
            If Len(numberHex) = 1 Then
                    numberHex = "0" & numberHex
            End If
            result = result & " " & numberHex
    Next
    getMemoryFormat = result
End Function

再看一下例子中要用到兩個字符:“編碼”,沒錯,是兩個繁體字,它們在各種字符集中的編碼如表2-9所示。

表2-9 “編碼”兩字的各種編碼

試驗程序如下,我們不輸出文本,而是輸出Stream對象中二進制數據的字符串表示形式。

StreamCharset.asp

<%@codepage=936%>
<! --#include File="getMemoryFormat.asp" -->
<%
Response.Charset="GBK"

Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 2      '文本方式
stream.Charset = "GBK"
stream.Open

'寫入文本
stream.WriteText "編碼"

'變更為二進制方式,讀取并輸出字符串形式
stream.Position = 0
stream.Type = 1      '二進制方式
response.write getMemoryFormat(stream.Read)

stream.close
Set stream = nothing
%>

運行結果如圖2-15所示。

圖2-15 Charset的作用

這表明Stream對象的4個字節中保存的二進制數據是:BE 8E B4 61。這是什么?沒錯,正是“編碼”兩個字對應的GBK的編碼。

我們再將程序中的Charset依次變更為Big5、Shift_JIS、Unicode和UTF-8,運行并匯總之后,我們得到表2-10。

表2-10 不同Charset的結果比較

對比一下,可以得知:

?Charset為GBK、Big5和Shift_JIS時,Stream中保存的就是字符對應的編碼,沒有前綴。

?Charset為Unicode時,保存的是低位在前的編碼,而且有兩個字節的前綴:FF FE。

?Charset為UTF-8時,有前綴EF BB BF。

再深入想一下,ASP運行時,內部變量都是以Unicode編碼形式存在的,也就是說,Stream的入口數據是Unicode編碼的。那么,我們可以說,向Stream對象寫入數據時,進行了Unicode編碼到Charset指定編碼的轉換。

對應地,使用ReadText方法讀取文本時,也進行了Charset指定編碼到Unicode編碼的轉換,Stream的出口數據是Unicode編碼的。還有一點,數據寫入之后,再變更Charset并不會影響已有的數據,只會影響之后寫入的數據。

范例如下所示。

StreamCharsetChange.asp

<%@codepage=936%>
<! --#include File="getMemoryFormat.asp" -->
<%
Response.Charset="GBK"

Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 2             '文本方式
stream.Charset = "GBK"
stream.Open

'寫入文本
stream.WriteText "編碼"

'變更Charset(指針需要移到位置0)
stream.Position = 0
stream.Charset = "UTF-8"

'再寫入文本
stream.Position = 4        '跳過已有的數據,以防被覆蓋
stream.WriteText "編碼"

'變更為二進制方式,讀取并輸出字符串形式
stream.Position = 0
stream.Type = 1             '二進制方式
response.write getMemoryFormat(stream.Read)

stream.close
Set stream = nothing
%>

運行結果如圖2-16所示。

圖2-16 變更Charset的影響

可以看到,變更Charset為UTF-8后,之前的4個字節并沒有變化,而后寫入的文字則是按UTF-8編碼寫入的。

5. 前綴寫入的時機

Charset為Unicode或UTF-8的時候,在位置0時調用WriteText方法,它就會自動寫入前綴。如Charset為UTF-8時,寫入一個字符“a”后,Stream的Size是4,而不是1。

寫入的前綴沒有任何特殊之處,它像普通的數據一樣,可以被覆蓋,所以處理的時候要注意跳過前綴。但覆蓋了也不要緊,把指針移到位置0再寫入數據,前綴就回來了。

中途變更Charset時要留意一下前綴。Unicode和UTF-8之間變更的時候,由于都有前綴,變更之后寫入的數據會覆蓋之前的前綴。從二者變更為GBK、Big5或Shift_JIS等沒有前綴的Charset時,前綴就遺留了下來,要留意它們的存在。

下面看一個例子,以加深理解。

StreamCharsetPrefix.asp

<%@codepage=936%>
<! --#include File="getMemoryFormat.asp" -->
<%
Response.Charset="GBK"

'輸出流中的數據
Sub printStream(stream)
    Dim savePosition
    savePosition = stream.Position           '保存指針位置

    '輸出數據
    stream.Position = 0
    stream.Type = 1
    response.write "流中的數據:" & getMemoryFormat(stream.read) & "<br><br>"

    stream.Position = 0
    stream.Type = 2
    stream.Position = savePosition           '恢復指針位置
End Sub

Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 2                              '文本方式
stream.Charset = "UTF-8"
stream.Open
stream.WriteText "哈哈"
Call printStream(stream)                     '看看流中的數據

stream.Position = 0
stream.Charset = "Unicode"                   '變更Charset為Unicode
Call printStream(stream)

stream.WriteText "a"       '在位置0寫入一個字符,將自動寫入前綴
Call printStream(stream)

stream.Position = 1        '在位置1寫入一個字符,將覆蓋前綴
stream.WriteText "b"
Call printStream(stream)

stream.Position = 0        '在位置0寫入一個字符,將自動寫入前綴
stream.WriteText "c"
Call printStream(stream)

stream.Close
Set stream = nothing
%>

運行結果如圖2-17所示。

圖2-17 Charset前綴的寫入時機

還有一點需要提醒一下,以文本方式保存到文件并且Charset為Unicode或UTF-8時,如果數據流中沒有前綴或者前綴被破壞,那么文件內容的前部還是會被插入前綴的。

主站蜘蛛池模板: 卢湾区| 七台河市| 汕头市| 荔波县| 武乡县| 福贡县| 固阳县| 内乡县| 当阳市| 吴旗县| 买车| 霍山县| 龙陵县| 西和县| 海原县| 军事| 叶城县| 鄂托克旗| 辉南县| 巨野县| 马鞍山市| 即墨市| 万全县| 霍城县| 嘉义县| 广河县| 宣恩县| 宜黄县| 太仓市| 武安市| 岑溪市| 霸州市| 德保县| 绥中县| 灵丘县| 上高县| 九龙城区| 修水县| 合江县| 读书| 镶黄旗|