【问题标题】:How to Rerun the TextStream.AtEndOfStream如何重新运行 TextStream.AtEndOfStream
【发布时间】:2015-10-12 21:04:42
【问题描述】:

我已成功运行下面的代码,逐行向浏览器显示文本文件:

<% 
    Filename = "/pages/test.txt"
    Set FSO = server.createObject("Scripting.FileSystemObject")
    Filepath = Server.MapPath(Filename)

    Set file = FSO.GetFile(Filepath)
    Set TextStream = file.OpenAsTextStream(1, -2)  

    Do While Not TextStream.AtEndOfStream  
            Line = TextStream.readline
            Response.Write Line & "<br>"
    Loop 

    Set TextStream = nothing
    Set FSO = nothing
%>

我想在Set TextStream = nothing 语句之前再运行一次Do While Not TextStream.AtEndOfStream 循环。

原来我不能“仅仅”复制Do While 循环并将其放在第一个实例的下方。 TextStream 不再有任何结果。

有没有办法将TextStream 对象重置回流的开头?

我可以将行存储在一个数组中并利用它,但我想看看是否有更简单的路线。

【问题讨论】:

  • 不使用 TextStream 对象,但如果您在读取流后切换到使用 ADO.Stream 对象,则可以使用 'Position` 属性将流位置设置为 0 并读取再次流。 ADODB.Stream 在这方面要灵活得多。

标签: vbscript asp-classic do-while filesystemobject


【解决方案1】:

很遗憾,无法手动将指针定位在TextStream 对象中。您可以Close TextStream 并重新打开它。或者,正如您暗示的那样,您可以只将文件读入一次数组。考虑到您将整个文件输出到网页,我会假设它不是非常大,因此将其存储在数组中不会太占用内存。

' Create an array containing each line from the text file...
a = Split(file.OpenAsTextStream(1, -2).ReadAll(), vbCrLf)

For i = 0 To UBound(a)
    Response.Write a(i) & "<br>"
Next

' Repeat the process...
For i = 0 To UBound(a)
    Response.Write a(i) & "<br>"
Next

您甚至可以用&lt;br&gt; 替换行尾并在一次操作中编写:

strText = Replace(file.OpenAsTextStream(1, -2).ReadAll(), vbCrLf, "<br>")

Response.Write strText
Response.Write strText    ' Write it again

【讨论】:

  • 是的,我也很怀疑。但是您的示例似乎也可行且容易。谢谢
  • @coffeemonitor 正如@Bond 指出的那样,仅当文件大小合理时才使用此方法。否则,您将遇到与内存相关的问题。在这种情况下,请随意打开、阅读和关闭几次。使用TextStream 对象绝对是一种内存友好的方式,将所有行读入数组或使用Adodb.Stream 都不是。我认为这对于运行良好的 Web 应用程序非常重要。
  • @Kul-Tigin Tired of FileSystemObject? Use the Stream Object Instead!。我还对您必须支持TextStreamADODB.Stream“记忆友好” 选项的说法感兴趣??
  • @Kul-Tigin 我同意关闭并重新打开总是更好,但建议 TextStreamADODB.Stream 更节省内存是无稽之谈。
  • @Kul-Tigin 我没有意识到TextStream 被分块并且在网络上找到任何明确的声明都没有产生任何结果。老实说,我多年来一直使用这两种方法,并没有发现任何一种方法都过于高效。将不得不做更多的研究。
【解决方案2】:

TextStream 对象的限制

Visual Basic 脚本运行时中的TextStream 对象的功能非常有限。

  • 仅向前读取,这意味着您无法返回到流中的较早点。

  • 写是全有或全无,当文件以ForWriting 模式打开时,文件的内容在被覆盖之前被截断(如pointed out 以避免这种使用ForAppending) em>.

还有其他方法吗?

介绍ADODB.Stream 对象!

幸运的是,ADODB 提供了一个更灵活的流对象 ADODB.Stream,它允许您打开文件(文本或二进制文件) 并控制 Position 属性允许您从流中的较早点读取。

类似的东西;

<%
Dim TextStream, Filename, Filepath    

Filename = "/pages/test.txt"
Filepath = Server.MapPath(Filename)

Set TextStream = Server.CreateObject("ADODB.Stream")
Call TextStream.Open()
TextStream.Type = adTypeText

Call TextStream.LoadFromFile(Filepath)

Do While Not TextStream.EOS
  Line = TextStream.ReadText(adReadLine)
  Call Response.Write(Line & "<br>")
Loop

'Reset stream back to start of the stream
TextStream.Position = 0

Do While Not TextStream.EOS
  Line = TextStream.ReadText(adReadLine)
  Call Response.Write(Line & "<br>")
Loop    

Call TextStream.Close()
Set TextStream = Nothing
%>

显然,这只是一个简单的示例(未经测试),说明如何使用ADODB.Stream。值得注意的是,您可以通过将 TextStream.Position = 0Do While 循环移动到可以重复使用并减少重复的单独函数来改进这一点。但是,出于此答案的目的,请保持简单。


更多信息

【讨论】:

  • 请记住,还有另一个选项 ForAppending 可以避免截断。 ForWriting 不仅仅是写作的选择。
  • @Kul-Tigin 是的,但ForAppending 在这种情况下没有用,我只是指出ForWriting 的行为可能会让一些人失望。我将编辑我的答案。
  • 很高兴看到你已经适应了提供替代品,Lankymart。
猜你喜欢
  • 2019-10-19
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多