ASP中FSO的神奇功能

什么是fso
    FSO是指文件系统对象,英文单词为File System Object。 
    FSO是ASP程序中的一个对文件操作的控件,通过编程,可以通过该控件对服务器进行读取、新建、修改、删除目录以及文件的操作。它是ASP编程中非常有用的一个控件。
    但大家可以想一下,在一台服务器上有许多虚拟用户,如果一个用户使用FSO删除别人的文件,那不是乱了套,所以基于安全考虑,不少的虚拟主机服务商干脆关掉了这个控件,但关掉此控件,有的有户想使用ASP生成文件又变成了不可能的事,所以如果关闭了FSO会让客户很不方便。
    所以你在购买虚拟主机时,一定要看看你的服务器有没有关闭FSO权限,用了FSO,我们就可以操纵的计算机文件系统,在这里是指位于web服务器之上。所以,确认你对此拥有合适的权限。理想情况下,你可以在自己的机器上建立一个web服务器,这样就能方便地进行测试。如果运行于Windows平台,如果你还不是很了解FSO,请试一试微软公司的免费个人Web服务器PWS,或windows2000的IIS.
怎样使用FSO?

FSO Model Objects FSO 模型对象
Drive Object 驱动器对象
Provides access to a disk or network drive
供存取磁盘或者网络驱动器
FileSystem Object 文件系统对象
Provides access to a computer's file system
供存取计算机的文件系统
Folder Object 文件夹对象
Provides access to all properties of a folder
供存取文件夹的所有属性
TextStream Object 文本流对象
Provides an easy way to access a file's contents 供存取文件内容

你可以使用上面的对象做计算机上的任何事情,也包括破坏活动 -( 所以,请小心使用FSO。在web环境中,存储信息是非常重要的,比如用户信息,日志文件,等等。FSO提供了一个强大且简单的方法高效率地保存数据。在这篇文章里面,着重讨论FileSystemObject和TextStream对象。

NOTE: FSO由微软公司提供支持,对于非Windows系统,FSO也许无法使用。

为了使用FSO来执行所有的工作,首先要创建对象,如果比较熟悉ASP中的对象,应该很容易看懂下面的代码: 

<%
Set fso = Server.CreateObject("Scripting.FileSystemObject")
%>

这样就建立了FSO并且赋予变量fso,接着就可以使用熟悉的object.method语法来执行文件系统的操作〔查看Visual Basic文档,获取更多的关于对象和对象向导编程的知识〕。在这里,我们可以使用fso.method 或者 fso.property,这些将在下面的例子中看到。

NOTE: FSO模型位于由微软提供的脚本运行时间DLL文件中,它是scrrun.dll。你可以在任何应用程序中引用这个DLL文件,比如MS Access,Word。 就是说,并非仅仅限制在ASP中应用它。

这里有一个简要的FSO方法列表:

File Methods FSO方法
CopyFile
Copies one or more files from one place to another
拷贝一个或者多个文件到新路径
CreateTextFile
Creates a file and returns a TextStream object
创建文件并且返回一个TextStream对象
DeleteFile
Deletes a file 删除一个文件
OpenTextFile
Opens a file and returns a TextStream object that can be used to read from or append to the file
打开文件并返回TextStream对象,以便读取或者追加

如果想了解完整的FSO方法与属性,请查阅微软MSDN。下面来看几个例子。

写文件 

假设你想创建一个简单的留言簿,你可以建立一个数据库,在其中存储用户的信息。然而,如果并不需要数据库的强大功能,使用FSO来存储信息将节省你的时间和金钱。并且,一些ISP也许限制了web上的数据库应用。

假设你在一个表单中收集了一些用户信息,这里是一个简单表单HTML代码:

< html >
< body >
< form  action ="formhandler.asp"  method ="post" >
< input  type ="text"  size ="10"  name ="username" >
< input  type ="text"  size ="10"  name ="homepage" >
< input  type ="text"  size ="10"  name ="Email" >
</ form >
</ body >
</ html >

再看看formhandler.asp中处理表单的代码:


path 
= "c: emp est.txt"
ForReading 
= 1, ForWriting = 2, ForAppending = 8
' open the file
set file = fso.opentextfile(path, ForAppending, TRUE)
' write the info to the file
file.write(strName) & vbcrlf
file.write(strHomePage) 
& vbcrlf
file.write(strEmail) 
& vbcrlf
' close and clean up
file.close
set file = nothing
set fso = nothing

 迄今为止,还没有新鲜的东西,无非是获取表单域的值并且赋值到变量。下面出现了有趣的部分 - 写文件


path 
= "c:/temp/test.txt"
ForReading 
= 1, ForWriting = 2, ForAppending = 8
' open the file
set file = fso.opentextfile(path, ForAppending, TRUE)
' write the info to the file
file.write(strName) & vbcrlf
file.write(strHomePage) 
& vbcrlf
file.write(strEmail) 
& vbcrlf
' close and clean up
file.close
set file = nothing
set fso = nothing
 

回想一下,OpenTextFile方法返回一个TextStream对象,它是FSO模型中的另外一个对象。TextStream对象揭示了操作文件内容的方法,比如写、读一行、跳过一行。VB常量vbcrlf产生一个换行符。

NOTE: 在OpentextFile的命令参数中定义了TRUE,这就告诉了系统,如果文件不存在,就创建它。如果文件不存在,并且没有定义TRUE参数,就会出错。

现在转到目录c:/temp,打开test.txt,你可以看到如下的信息:  

User's name
User's home page
User's email

当然,这些单词可以被输入在表单中的任何内容所替换。  

读文件

现在已经有了一些用户信息保存在文件中,就像一个简单的数据库。假设有一个用户想了解所有的访问者,就要从登记的信息中分离出相关部分,因为没有象数据库一样拥有结构化的列。

我们知道,在所创建的文件中,第1行是用户名,第2行是他们的主页,第3行是他们的电子邮件地址。随后登记的用户也是按照这样的结构存储他们的信息,所以每3行将包含一个用户的登记信息。知道了这些,就可以编写下面的代码来显示信息:

<%
' create the fso object
set fso = Server.Createobject("Scripting.FileSystemObject")
path 
= "c: emp est.txt"
' open the file
set file = fso.opentextfile(path, 1)  <-- For reading

 接着,分析每一行,并且格式化数据:


do until file.AtEndOfStream
        Response.write(
"Name: " & file.ReadLine & " ")
        Response.write(
"Home Page: " & file.ReadLine & " ")
        Response.write(
"Email: " & file.ReadLine & "<p>")
loop
' close and clean up
file.close
set file = nothing
set fso = nothing
%>

 

NOTE: 这里仅仅做了一个非常简单的输出,但是你可以根据情况包含表格或者DHTML表单信息

如果已经正确地建立并写入了文件,上面的小小循环将合适地列出数据库中的每一个人的信息。ReadLine方法读取1行内容,直到遇到换行符,随后的ReadLine调用将读取下一行。AtEndOfStream是TextStream对象的属性,它告诉我们何时遇到文件的尾部。

假设由于某种原因,我们没有正确地形成文件,如果一个用户只有2行信息而不是3行,那么就会产生一些错误。我们这里的循环取回文件中的下3行信息,如果没有3行多的信息,就将出现如下的错误信息:

Server object error 'ASP 0177 : 800a003e'

所以,一定要添加一些错误处理代码,以防文件中插入了多余的行或者少了必要的行信息。

权限许可

上面讨论了基本知识,然后说说权限许可的问题。FSO以创建它的用户帐户权限运行,换言之,如果有人从Internet上访问你的页面,那么这个internet帐户就创建FSO。如果以administrator的身份登录计算机,并且登录页面,那么administrator帐户就创建了FSO。这是非常重要的,因为一定的帐户拥有一定的权限,并且FSO需要一些权限从而能完整的执行功能。

internet帐户(IUSER_MachineName,MachineName是服务器的名字)一般只拥有读权限,这意味着用户将不能写入留言簿文件。然而,有几个选择可以绕过这个问题。

首先,也是很困难的,是要求用户在填写留言簿前登录到服务器。然而,留言簿的要点是从匿名用户处收集信息,如果要求用户登录,就必须要知道他们是谁。因此,跳过这个选择,看下一个。

第2个方法是创建一个目录或者文件,IUSER_MachineName用户对此有写权限。这样做可能开放了一些潜在的安全漏洞,因为任何知道正确目录并具备一定web技巧的人就能在服务器上填充内容。这是一个很严重的禁忌。所以你必须确认在隐藏的场所保存了这些可写目录的信息,并且尽可能地将这些目录设置在web目录结构以外(比如在Windows下,这是一个不在inetpub目录下的一个目录)。

为web站点建立搜索功能

你也许想:好,现在我知道如何写入文件了。但能做到更多一些吗?下面来试一试为web站点建立一个搜索功能。

建立搜索引擎的关键是递归。主要地,编写一段代码搜索目录下的文件,然后对所有的目录循环执行同样的代码。因为不能确定总共有多少个子目录,所以必须一遍又一遍地执行搜索代码,直到结束。递归调用非常好!

下面来创建搜索页面。假设已经建立了一个HTML表单,用户在其中输入一个搜索字符串。 


Dim objFolder
Dim strSearchText
Dim objFSO
strSearchText 
= Request.Form("SearchText")  <-- The search string
' create the FSO and Folder objects
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(Server.MapPath("/"))

Search objFolder

 上面的代码简单地初始化变量,Search函数执行搜索功能,描述如下: 


Function Search(objFolder)
  
Dim objSubFolder
  
'loop through every file in the current
folder
  
For Each objFile in objFolder.Files
    
Set objTextStream = objFSO.OpenTextFile(objFile.Path,1<-- For Reading
        
'read the file's contents into avariable
        strFileContents = objTextStream.ReadAll
        
'if the search string is in the file, then write a link
        ' to the file
        If InStr(1, strFileContents, strSearchText, 1then
           Response.Write 
"<A HREF=""/" & objFile.Name & _
                
""">" & objFile.Name & "</A><BR>"
           bolFileFound 
= True
        
End If
        objTextStream.Close
  
Next
  
'Here's the recursion part - for each
  ' subfolder in this directory, run the Search function again

  
For Each objSubFolder in objFolder.SubFolders
        Search objSubFolder
  
Next
End Function
 
NOTE: 为了能打开文件,FSO需要实际的文件路径,而不是web路径。
比如,是c:/inetpub/wwwroot/temp/index.html, 而不是 www.enfused.com/temp/index.html 或 /temp/index.html. 为了将后者转换为前者,使用Server.MapPath("filename"), filename表示web路径名。

上面的代码将在你指定的初始目录下的文件夹的每一个子目录中执行,在这里,初始目录是指web根目录“/”。然后就简单地打开目录下的每一个文件,看看其中是否包含指定的字符串,如果找到字符串就显示那个文件的链接。

注意,随着文件和子目录数量的增加,搜索花费的时间也将增加。如果需要繁重的搜索工作,建议你采取其他的方法,比如微软公司的索引服务器Index Server。

进行内容管理

到此,你对FSO可能已经有了很好的体会。让我们再深入研究一步,来解决更复杂的难题。

Content management is being able to keep track of, manipulate, and generally perform tasks with content, typically documents in a web environment. Smart content management does all that in an easy, painless fashion. (Check out this article to study up on content management.) Behind the scenes of such an application is heavy duty file manipulation. Once again, enter the FSO. We need to be able to move, delete, rename, and create files, and our friend the FSO steps in nicely. In the article above, we discuss a submission system for writers to publish their content. What we don't mention is exactly what to do with the file once it's up.

首先,你可能希望对文件改名。为了跟踪所有的文档,你将要重新命名它们以便唯一,这样就可以被系统容易地区别。很不幸,FSO不允许简单的文件改名操作,所以我们不得不修改一下。 FSO能力的不足在这里却成了优势,我们可以一次执行2步。首先,打开文件并读入文件的内容。假设这里要创建一个唯一的文件夹和一个唯一的文件来存储文章。然而,因为文件夹的路径每天都将改变,所以必须首先检查是否文件夹已经存在,如果不存在,就创建它。这在if not fso.folderexists代码段完成。然后,取得那个路径,创建一个新的文件。新文件建立完成后,删除掉旧文件,这通过fso.DeleteFile来完成。

 

<%
' create the fso object
set fso = Server.Createobject("Scripting.FileSystemObject")
path 
= "c: emp est.txt"
strDate 
= Replace(Date(), "/""")
strDir 
= "c:inetpubwwwrootarticles" & strDate
strNewFileName 
= Hour(Now& "_" & Minute(Now& "_" &
second(Now& ".html"
' open the old file
set file = fso.opentextfile(path, 1)  <-- For reading
strText 
= file.readall
set file = nothing
' check for and/or create folder
if not fso.folderexists(Server.MapPath(strDir)) then
        
set f = fso.CreateFolder(Server.MapPath(strDir))
else
        
set f = fso.GetFolder(Server.MapPath(strDir))
end if
' create and write new file
set file = fso.Createtextfile(f.path & "" & strNewFileName)
file.write(strText)
set f = nothing
file.close
set file = nothing
' delete the old file
fso.DeleteFile(path & "" & rst("FileName"& i)
' clean up
set fso = nothing
%>

这2步就是:对文件改名,然后移动到一个更合适的目录下。注意,在这里还可以对文件进行更多地操作,比如在写入新文件前进行一下内容的编辑。

它不能做什么? 

FSO确实存在一些弱点——比如,它很难处理二进制文件,这包括Word文档、许多图形格式的文件和其他一些文件。然而你仍然可以用其他的方式操作这些文件——移动它们、删除它们,等等。你不能做的就是对它们进行打开或者写操作。 

另外一个限制是对于文件长度的问题。当立刻读写一些内容时,所有的信息都存储在内存中 - 内容越多,消耗的内存就越大。这将使每个工作都变得慢起来。所以,如果需要操作非常大的文件,或者大量的小文件时,考虑将文件分割成小块,并且经常的清除内存。将应用程序融入进COM对象组件,也能大大地提高程序的速度。

同样,你也不能使用FSO来管理权限以及文件、文件夹的属性,执行安全加密的一个很好方法就是将前面提到的留言簿文件设置为只读,在需要时再设置为可写,然后再修改回来。这个方法经常在CGI和Perl使用,但是很不幸,还没有令人满意的方法来用FSO实现。

它还能做什么? 

在FSO中还有许多很棒的功能,但许多人没有意识到。这些功能常常是在你感到做某些事情很难后才发现的,这时你经常要感叹到:要是我早知道这个方法就好了!

下面列举一下这些不常用但是却非常酷的功能:

Little Known FSO Features 很少被了解的FSO功能
GetSpecialFolder Method
Returns the path to a special Windows folder: the Windows installation folder; the system folder; and the Windows Temporary folder. Syntax: FSO.GetSpecialFolder([0, 1, or 2]) 返回特定的Windows文件夹的路径: Windows安装目录;Windows系统目录;Windows临时目录 FSO.GetSpecialFolder([0, 1, or 2]) 
GetTempName Method
Returns a randomly generated temporary file or folder name. Useful when you need to store temporary data (i.e. when you run into the file size limitation described above).返回一个随机产生的文件或者目录名字,用于需要存储临时数据时
GetAbsolutePathName Method
Returns the absolute path of a folder (similar to Server.MapPath).返回文件夹的绝对路径(类似于Server.MapPath) For example, FSO.GetAbsolutePathName("region") will return something like "c:/mydocs/myfolder/region" 
GetExtensionName Method
Returns the extension for the last item in a path 返回路径中最后部分的扩展名(i.e. FSO.GetExtensionName("c:/docs/test.txt") will return txt)
GetBaseName and GetParentFolder Methods
Returns the base and parent folder name respectively of last item in a path返回路径中最后部分的父文件夹 (i.e. FSO.GetParentFolder ("c:/docs/mydocs") will return 'docs')
Drives Property
Returns a collection of all the drive objects available on the local machine. This is helpful if you ever want to build an explorer type interface.返回所有本地可用驱动器的集合,用于建立资源浏览器样的用户接口

使用上面的功能时,最好建立好出错处理的代码。因为如果需要的参数不存在,将会产生麻烦的信息。

总结

如我们所见,FSO非常有用,这里介绍的仅仅是冰山一角。你可以使用FSO建立功能强大的应用程序,简单地完成许多任务。

The takeaway here is that you can build very powerful applications with the FSO, as well as accomplish some simples tasks more easily. Keep this one in your toolbelt!

Happy scripting!

About the Author

Chris Payne Currently lives in the Boston area. He has been building database driven web sites for several years. In February 2000, he cofounded Enfused Media, Inc, a web development/gaming firm. The first development from EMI was www.enfused.com, a massive gaming portal for gamers as well as the gaming business. His offline time is spent with his fiance and their tropical fish. Email: clpayne@enfused.com  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值