深入解析ASP核心技术
上QQ阅读APP看书,第一时间看更新

2.3.5 操作Stream对象

Stream对象就像一个容器,刚开始的时候,它是空的,我们写入一些数据的时候,它就自动扩大,以容纳这些数据。我们紧接着再写入一些数据,它就再次扩大,以此类推。但是,它只会主动扩大,而不会主动缩小,缩小这个动作需要我们指示它来做。Write、WriteText和CopyTo方法,都是从当前位置开始写入数据,写到哪里算哪里,之后的数据不会被删除。

下面看一下Stream对象的基本操作。

1. Stream对象的大小

Size属性返回当前Stream对象中数据的字节数,不管是文本方式还是二进制方式,返回的始终是字节数。对于从文件读入的数据,Size属性不一定代表文件的大小,因为数据的开头可能加入了前缀。

2. 移动指针

变更Position属性即可,最小为0,最大为Size属性的值,超过则报错。指针移动的单位是字节。

3. 当前位置是否是末尾

使用EOS属性即可,如果是末尾,即Position等于Size的时候返回True,否则返回False。

4. 追加数据

当指针位于流的末尾时,即EOS属性为True时,写入的数据是追加到流的末尾的。如果想在流的中间插入数据,那么,很遗憾,没有直接的方法。但我们可以将数据复制到另一个Stream对象,在复制的过程中插入数据即可,然后使用复制后的Stream对象。

5. 修改数据

移动指针到指定的位置,再次写入数据即可,写入几个字节就覆盖几个字节。如果超过了流的末尾,则流会自动扩大,以容纳多余的数据。

6. 截断数据

如果某个位置之后的数据不要了,可以将指针移动到那里,然后调用SetEOS方法,之后的数据就会被抛弃,当前位置变为流的末尾,流的Size属性也变小了。如果流中间位置的某段数据不要了,想要截断抛弃,也是没有直接的方法的,也可以通过Stream对象间的数据复制来间接实现。

下面的例子演示的是Size属性、Position属性和EOS属性。

StreamPosition.asp

<%@codepage=936%>
<%
Response.Charset="GBK"
Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 2    '文本方式
stream.Charset = "GBK"
stream.Open
stream.WriteText "編碼"

'输出大小等信息
response.write "大小:" & stream.Size & "<br>"
response.write "位置:" &stream.Position & "<br>"
response.write "末尾:" &stream.EOS & "<br>"
response.write "字符长度:" &Len(stream.ReadText) & "<br><br>"

'移动到位置0,即从第一个字节开始读取
stream.Position = 0
response.write "字符:" &stream.ReadText(1) & "<br>"
response.write "位置:" &stream.Position & "<br>"
response.write "末尾:" &stream.EOS & "<br><br>"

'再读一个字符
response.write "字符:" &stream.ReadText(1) & "<br>"
response.write "位置:" &stream.Position & "<br>"
response.write "末尾:" &stream.EOS & "<br>"

stream.close
Set stream = nothing
%>

运行结果如图2-20所示。

图2-20 Stream对象操作范例

当指针指向流的末尾时,读取数据将得到空字符串(图中输出字符长度为0),同时指针是不会移动的,仍然指向末尾。

如果将Charset变更为UTF-8,则运行结果如图2-21所示。流的长度变为9,因为在UTF-8编码中,一个汉字占3个字节,两个汉字是6个字节,另外还有3个字节的前缀。读取第一个字符的时候,指针从0跳到了6,它自动跳过了3个字节的前缀。

图2-21 Charset为UTF-8时的运行结果

下面看一下追加数据、修改数据和截断数据的范例。

StreamCutData.asp

<%@codepage=936%>
<%
Response.Charset="GBK"
twoSpace = "&nbsp; &nbsp; "

'输出流中的数据
Sub printStream(stream)
    Dim savePosition
    savePosition = stream.Position           '保存指针位置

    '输出数据
    stream.Position = 0
    response.write "流中的数据:" & stream.ReadText & "<br><br>"

    stream.Position = savePosition           '恢复指针位置
End Sub

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

'写入数据
stream.WriteText "0000000000"
response.write "大小:" & stream.Size & twoSpace
response.write "位置:" &stream.Position & "<br>"
Call printStream(stream)

'继续写入数据,此时数据是追加的
stream.WriteText "1111111111"
response.write "大小:" & stream.Size & twoSpace
response.write "位置:" &stream.Position & "<br>"
Call printStream(stream)

'移动到位置5
stream.Position = 5
stream.WriteText "22222"
response.write "大小:" & stream.Size & twoSpace
response.write "位置:" &stream.Position & "<br>"
Call printStream(stream)

'移动到位置15
stream.Position = 15
stream.WriteText "3333333333"
response.write "大小:" & stream.Size & twoSpace
response.write "位置:" &stream.Position & "<br>"
Call printStream(stream)

'移动到位置20,截断数据
stream.Position = 20
stream.SetEOS
response.write "大小:" & stream.Size & twoSpace
response.write "位置:" &stream.Position & "<br>"
call printStream(stream)

stream.close
Set stream = nothing
%>

运行结果如图2-22所示。

图2-22 追加数据、修改数据和截断数据的范例