在ASP.NET页中读取文本文件
2024-07-10 12:55:53
供稿:网友
国内最大的酷站演示中心!
简介
在现实世界中,人们经常希望能够把某个文本文件的部分或全部内容保存到一个 web 网页变量中。在经典的 asp 中,只要简单地使用 filesystemobject 就能做到了。其实,在 aspfaqs.com 中就有一个 faq 栏目专门讨论 filesystemobject 。
可是在 asp.net 中呢?filesystemobject 当然还可以用,不过,经验表明这么做会严重影响服务器性能。因此,最好还是使用 .net 框架本身提供的类来读取文件。本文要介绍的是如何读取文本文件;今后我还会介绍如何使用 .net 框架类来读取 xml 文件。
file ? fileinfo ?
在 .net 框架中,有许多方法可以打开文本文件。有趣的是,所有这么方法集中在 system.io 名字空间的两个类中。它们是 file 类和 fileinfo 类。两个类之间的区别很小。file 类的方法全都是共享方法(静态方法),而fileinfo 类有例外。共享方法就是不用创建类实例也能调用的方法。假设要用这两个类删除文件,则可以这么做:
'使用 file 类
file.delete(filename)
'使用 fileinfo 类
dim finfo as fileinfo
finfo = new fileinfo(filename)
finfo.delete()
请注意,file 类的 delete 方法只带一个参数,即待删的文件,而且不必对 file 类进行实例化就能调用。再来看 fileinfo 类,它的 delete 方法不带参数,因为文件名在 fileinfo 类实例的构造器中指定。
就我个人而言,我偏爱 file ,因此就拿它来作示范吧。我敢打赌 file 类的效率稍微高那么一点点,因为使用它就不会因为类的实例化而烦恼;不过那只是猜测而已。(如果感兴趣,请不妨编程比较一下它们的性能。当你完成之后,请把结果告诉我!)
打开文件
打开文本文件最简单的途径是调用 opentext 方法,它将按照 utf-8 (ascii) 格式打开文本文件。你还可以选择通用的 open 方法,以便指定文件操作模式 (create/open/append/truncate) 、操作权限 (read/write/read-write) 和文件共享权限了;可既然你只需要读取文本文件,那么相对简单的 opentext 方法也就足以应付了。
opentext 方法返回一个 streamreader 对象,只要访问该对象就能从刚才打开的文件中读取文本内容。因此,打开文件所用的 asp.net 代码大致如下:
<%@ import namespace="system.io" %>
<script language="vb" runat="server">
sub page_load(sender as object, e as eventargs)
'以“只读”方式打开文件
dim filename as string = server.mappath("rand.txt")
'创建 streamreader 类实例,准备读取文件内容
dim objstreamreader as streamreader
objstreamreader = file.opentext(filename)
...
请注意,代码的第一行导入了 system.io 命名空间。这是因为 file 类就属于此命名空间。还有,在 page_load 事件处理程序中,创建了一个字符串 filename ,其内容就是欲打开的文件的物理路径(比如 c:/inetpub/wwwroot/rand.txt)。最后,在 asp.net 中的 server.mappath 也和经典的 asp 中相同 (为了更好地理解 server.mappath ,请别忘了阅读位于 http://aspnet.4guysfromrolla.com/webtech/121799-1.shtml 的《using server.mappath》)。
从文件中读取文本
现在,你面临两种选择:(1) 读取文件当前位置的下一行文本到字符串;(2) 读取整个文件的文本到字符串。如果是后者,你只需调用 readtoend() 方法即可:
...
'现在,读取整个文件的文本到字符串
dim contents as string = objstreamreader.readtoend()
...
但如果是前者呢?在读取下一行文本之前,须得先确认尚有文本可读。为此,可以尝试 peek() 方法。peek() 方法能够返回指定流的下一个文本字符,却不把该字符从流中删掉;如果流中不再有文本字符可读,则返回 -1。接下来,只要循环遍历 peek() 的返回值:loop while objstreamreader.peek() <> -1 ,并且在循环内部使用 readline() 方法读取下一行文本就行了:
while objstreamreader.peek() <> -1
somestring = objstreamreader.readline()
'... do whatever else you need to do ...
end while
切记!关闭 streamreader 对象!
当你读完全部文本,并且不再操作此文件时,千万记住要使用 close() 方法关闭 streamreader 对象,以关闭此文件。如果你忘记这么做,则 asp.net 操作进程将保持对此文件的只读锁定状态,因而当你换用其它帐号操作此文件时将会遇到错误信息 “access denied”(拒绝访问) ;而且当你试图删除或覆盖此文件时也将遇到同样的错误信息;只不过 asp.net 本身对此文件的操作却不受影响。因此,一定要在完成操作之后关闭文件。
附:完整的示范程序
<%@ import namespace="system.io" %>
<script language="vb" runat="server">
sub page_load(sender as object, e as eventargs)
'以只读方式打开一个文件
dim filename as string = server.mappath("rand.txt")
'实例化一个 streamreader 对象用于读取文件
dim objstreamreader as streamreader
objstreamreader = file.opentext(filename)
'现在,读入整个文件的文本并保存到一个字符串里
dim contents as string = objstreamreader.readtoend()
'在一个 web 控件中显示文本
lblrawoutput.text = contents
'为了在便于浏览,最好把回车字符替换成 <br>
lblniceroutput.text = contents.replace(vbcrlf, "<br>")
objstreamreader.close()
end sub
</script>
<b>raw file output</b><br />
<asp:label runat="server" id="lblrawoutput" />
<p>
<b>nicer output</b><br />
<asp:label runat="server" id="lblniceroutput" font-name="verdana" />
结论
本文附带了一个示范程序的源代码。该程序简单地打开一个硬编码的(hard-coded)文本文件,然后把其中的所有文本一次性保存到指定字符串里,再把字符串的值显示在服务器端的一个 web 控件 label 中。
你看,通过 asp.net 页面读取文本文件内容实在不难。虽然在语法上和经典 asp 的 filesystemobject 对象有些差异,但是学起来真的很容易。为了更好的掌握如何在 asp.net 中读写文件,请务必阅读 《asp.net: tips, tutorials, and code》一书 (样本见 http://www.4guysfromrolla.com/webtech/chapters/aspnet2 )!