ASP中FSO功能詳細介紹
在ASP中,FSO的意思是File System Object,即檔案系統物件。
我們將要操縱的計算機檔案系統,在這裡是指位於web伺服器之上。所以,確認你對此擁有合適的許可權。理想情況下,你可以在自己的機器上建立一個web伺服器,這樣就能方便地進行測試。如果運行於Windows平臺,請試一試微軟公司的免費個人Web伺服器PWS。
FSO 模型物件
Drive Object:驅動器物件 供存取磁碟或者網路驅動器
FileSystemObject Object:檔案系統物件 供存取計算機的檔案系統
Folder Object:資料夾物件 供存取資料夾的所有屬性
TextStream Object:文字流物件 供存取檔案內容
你可以使用上面的物件做計算機上的任何事情,也包括破壞活動 ;-( 所以,請小心使用FSO。在web環境中,儲存資訊是非常重要的,比如使用者資訊,日誌檔案,等等。FSO提供了一個強大且簡單的方法高效率地儲存資料。在這篇文章裡面,著重討論FileSystemObject和TextStream物件。
FSO由微軟公司提供支援,對於非Windows系統,大概不能再使用ASP。
怎麼樣使用FSO?
為了使用FSO來執行所有的工作,首先要建立物件,程式碼就象下面這樣:
< %
Set fso = Server.CreateObject("Scripting.FileSystemObject")
% >
這樣就建立了FSO並且賦予變數fso,接著就可以使用熟悉的object.method語法來執行檔案系統的操作〔檢視Visual Basic文件,獲取更多的關於物件和物件嚮導程式設計的知識〕。在這裡,我們可以使用fso.method 或者 fso.property,這些將在下面的例子中看到。
FSO模型位於由微軟提供的指令碼執行時間DLL檔案中,它是scrrun.dll。你可以在任何應用程式中引用這個DLL檔案,比如MS Access,Word。 就是說,並非僅僅限制在ASP中應用它。
這裡有一個簡要的FSO方法列表:
FSO方法
CopyFile 拷貝一個或者多個檔案到新路徑
CreateTextFile 建立檔案並且返回一個TextStream物件
DeleteFile 刪除一個檔案
OpenTextFile 開啟檔案並且返回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中處理表單的程式碼:
< %
' Get form info
strName = Request.Form("username")
strHomePage = Request.Form("homepage")
strEmail = Request.Form("Email")
' create the fso object
Set fso = Server.CreateObject("Scripting.FileSystemObject")
迄今為止,還沒有新鮮的東西,無非是獲取表單域的值並且賦值到變數。下面出現了有趣的部分 - 寫檔案:
path = "c: emp est.txt"
ForReading = 1, ForWriting = 2, ForAppending = 3
' 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產生一個換行符。
在OpentextFile的命令引數中定義了TRUE,這就告訴了系統,如果檔案不存在,就建立它。如果檔案不存在,並且沒有定義TRUE引數,就會出錯。
現在轉到目錄c: emp,開啟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
%>
這裡僅僅做了一個非常簡單的輸出,但是你可以根據情況包含表格或者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站點建立一個搜尋功能。
建立搜尋引擎的關鍵是遞迴。主要地,編寫一段程式碼搜尋目錄下的檔案,然後對所有的目錄迴圈執行同樣的程式碼。因
為不能確定總共有多少個子目錄,所以必須一遍又一遍地執行搜尋程式碼,直到結束。遞迴呼叫非常好!
下面來建立搜尋頁面。假設已經建立了一個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 a
variable
strFileContents = objTextStream.ReadAll
'if the search string is in the file, then
write a link
' to the file
If InStr(1, strFileContents, strSearchText, 1) then
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
為了能開啟檔案,FSO需要實際的檔案路徑,而不是web路徑。比如,是c:inetpubwwwroot empindex.html, 而不是
www.enfused.com/temp/index.html 或者 /temp/index.html。 為了將後者轉換為前者,使用Server.MapPath
("filename"), filename表示web路徑名。
上面的程式碼將在你指定的初始目錄下的資料夾的每一個子目錄中執行,在這裡,初始目錄是指web根目錄“/”。然後
就簡單地開啟目錄下的每一個檔案,看看其中是否包含指定的字串,如果找到字串就顯示那個檔案的連結。
注意,隨著檔案和子目錄數量的增加,搜尋花費的時間也將增加。如果需要繁重的搜尋工作,建議你採取其他的方
法,比如微軟公司的索引伺服器Index Server。
到此,你對FSO可能已經有了很好的體會。讓我們再深入研究一步,來解決更復雜的難題。
首先,你可能希望對檔案改名。為了跟蹤所有的文件,你將要重新命名它們以便唯一,這樣就可以被系統容易地區
別。很不幸,FSO不允許簡單的檔案改名操作,所以我們不得不修改一下。
< %
' 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
%>
FSO能力的不足在這裡卻成了優勢,我們可以一次執行2步。首先,開啟檔案並讀入檔案的內容。假設這裡要建立一個
唯一的資料夾和一個唯一的檔案來儲存文章。然而,因為資料夾的路徑每天都將改變,所以必須首先檢查是否資料夾已經
存在,如果不存在,就建立它。這在if not fso.folderexists程式碼段完成。然後,取得那個路徑,建立一個新的檔案。新
檔案建立完成後,刪除掉舊檔案,這通過fso.DeleteFile來完成。
這2步就是:對檔案改名,然後移動到一個更合適的目錄下。注意,在這裡還可以對檔案進行更多地操作,比如在寫
入新檔案前進行一下內容的編輯。
FSO確實存在一些弱點 - 比如,它很難處理二進位制檔案,這包括Word文件、許多圖形格式的檔案和其他一些檔案。然而你仍然可以用其他的方式操作這些檔案 - 移動它們、刪除它們,等等。你不能做的就是對它們進行開啟或者寫操作。
另外一個限制是對於檔案長度的問題。當立刻讀寫一些內容時,所有的資訊都儲存在記憶體中 - 內容越多,消耗的記憶體就越大。這將使每個工作都變得慢起來。所以,如果需要操作非常大的檔案,或者大量的小檔案時,考慮將檔案分割成小塊,並且經常的清除記憶體。將應用程式融入進COM物件元件,也能大大地提高程式的速度。
同樣,你也不能使用FSO來管理許可權以及檔案、資料夾的屬性,執行安全加密的一個很好方法就是將前面提到的留言簿檔案設定為只讀,在需要時再設定為可寫,然後再修改回來。這個方法經常在CGI和Perl使用,但是很不幸,還沒有令人滿意的方法來用FSO實現。
還能用FSO做什麼?
在FSO中還有許多很棒的功能,但許多人沒有意識到。這些功能常常是在你感到做某些事情很難後才發現的,這時你經常要感嘆到:要是我早知道這個方法就好了!
下面列舉一下這些不常用但是卻非常酷的功能:
很少被瞭解的FSO功能
GetSpecialFolder Method 返回特定的Windows資料夾的路徑: Windows安裝目錄;Windows系統目錄;Windows臨時目錄 FSO.GetSpecialFolder([0, 1, or 2])
GetTempName Method 返回一個隨機產生的檔案或者目錄名字,用於需要儲存臨時資料時
GetAbsolutePathName Method 返回資料夾的絕對路徑(類似於Server.MapPath)。
比如,FSO.GetAbsolutePathName("region") 將返回類似於下面的結果:"c:mydocsmyfolder egion"
GetExtensionName Method 返回路徑中最後部分的副檔名
(比如:FSO.GetExtensionName("c:docs est.txt") 將返回txt)
GetBaseName and GetParentFolder Methods 返回路徑中最後部分的父資料夾
(比如:FSO.GetParentFolder ("c:docsmydocs") 將返回'docs')
Drives Property 返回所有本地可用驅動器的集合,用於建立資源瀏覽器樣的使用者介面。
使用上面的功能時,最好建立好出錯處理的程式碼。因為如果需要的引數不存在,將會產生麻煩的資訊。
總結
如我們所見,FSO非常有用,這裡介紹的僅僅是冰山一角。你可以使用FSO建立功能強大的應用程式,簡單地完成許多工。