ASP.NET 2.0網頁製作徹底研究

Download Report

Transcript ASP.NET 2.0網頁製作徹底研究

第7章 Web伺服器檔案與XML文
件的處理





7-1
7-2
7-3
7-4
7-5
System.IO名稱空間的基礎
伺服器的資料夾與檔案操作
文字檔案讀寫、搜尋和取代
二進位檔案的處理
XML文件的處理
7-1 System.IO名稱空間的基礎



7-1-1 在Web網站儲存資料的方式
7-1-2 System.IO名稱空間
7-1-3 取得伺服端檔案或資料夾的路徑
7-1-1 在Web網站儲存資料的方
式

在ASP.NET程式建立的Web網站,可以需要儲存
一些暫時或永久的資料,以幫助Web網站的瀏覽
和ASP.NET程式的執行,如下所示:
• 使用文字檔案儲存:將資料儲存成Web伺服器的文字
檔案。在ASP.NET程式是使用System.IO名稱空間的
類別來處理文字檔案的資料。
• 使用XML文件儲存:將資料儲存成XML文件。
ASP.NET程式是使用System.Xml名稱空間的類別來
處理XML文件。
• 使用資料庫儲存:將資料儲存在伺服端的資料庫系統,
也就是所謂的網頁資料庫,在第8~9章筆者將詳細討
論此部分。
7-1-2 System.IO名稱空間

System.IO名稱空間提供檔案和資料夾處理的相
關類別。其主要的類別,如下表所示:
類別
說明
Directory
提供類別方法來建立、移動和顯示資料夾與子資料夾清單
DirectoryInfo 提供物件的實例方法來建立、移動和顯示資料夾與子資料夾清單
File
提供類別方法來建立、複製、刪除、移動和開啟檔案,其目的是
建立 FileStream 物件
FileInfo
提供物件的實例方法來建立、複製、刪除、移動和開啟檔案,其
目的是建立 FileStream 物件
StreamReader 實作 TextReader 類別,可以使用位元組串流來讀取指定編碼的文
字檔案
StreamWriter 實作 TextWriter 類別,可以使用位元組串流來寫入指定編碼的文
字檔案
FileStream 建立檔案的串流,支援同步與非同步的讀取與寫入,可以處理二
進位檔案
7-1-3 取得伺服端檔案或資料夾的路
徑-取得ASP.NET程式的實際路徑

ASP.NET程式檔案所在的虛擬目錄,可以使用
ServerVariables集合物件的PATH_INFO來取得,
如下所示:
Request.ServerVariables("PATH_INFO")

程式碼取得目前執行ASP.NET檔案的虛擬目錄。
只需配合Server.MapPath()方法,就可以轉換
成實際路徑,如下所示:
path1 = Server.MapPath( _
Request.ServerVariables("PATH_INFO"))
7-1-3 取得伺服端檔案或資料夾的路
徑-取得指定目錄的實際路徑

同樣方法,可以取得指定虛擬目錄的實際
目錄。例如:取得Web伺服器主目錄的實
際路徑,如下所示:
path2 = Server.MapPath("/")

至於取得指定虛擬目錄的實際路徑,如下
所示:
path3 = Server.MapPath("/Ch07")
7-2 伺服器的資料夾與檔案操作





7-2-1
7-2-2
7-2-3
7-2-4
7-2-5
顯示伺服器的磁碟清單
顯示資料夾清單和相關資訊
資料夾的處理
顯示檔案清單和資訊
檔案處理
7-2-1 顯示伺服器的磁碟清單

我們可以使用Directory類別的
GetLogicalDrives()方法,來取得所有Web伺服
器的邏輯磁碟清單,如下所示:
Dim arrDrives() As String =
Directory.GetLogicalDrives()

程式碼取得磁碟機清單的字串陣列後,就可以使
用迴路顯示陣列內容,也就是所有磁碟機代碼,
如下所示:
For i = 0 To arrDrives.Length - 1
Response.Write(arrDrives(i) & " ")
Next
7-2-2 顯示資料夾清單和相關資訊顯示資料夾下子資料夾清單1

在DirectoryInfo類別的GetDirectories()方法
可以取得資料夾清單,如下所示:
Dim dInfo As DirectoryInfo = _
new DirectoryInfo(path)
Try
Dim subDirs() As DirectoryInfo = _
dInfo.GetDirectories()
………
Catch ex As DirectoryNotFoundException
s = "<font color=red>" & ex.Message & _
"</font>"
End Try
7-2-2 顯示資料夾清單和相關資訊顯示資料夾下子資料夾清單2

程式碼建立DirectoryInfo物件後,使用
GetDirectories()方法取得子資料夾清單的
DirectoryInfo物件陣列,然後就可以使用迴路顯
示子資料夾清單,如下所示:
For i = 0 To subDirs.Length - 1
s &= "<tr><td>" & subDirs(i).Name & _
"</td>"
Next

程式碼在取得指定DirectoryInfo物件後,使用
Name屬性取得資料夾名稱。
7-2-2 顯示資料夾清單和相關資訊DirectoryInfo物件的屬性

在取得DirectoryInfo物件後,就可以使用屬性來
取得資料夾資訊,相關屬性如下表所示:
資料夾屬性
Name
FullName
Parent
Attributes
CreationTime
LastAccessTime
LastWriteTime
說明
資料夾名稱
資料夾的全名
取得父資料夾的 DirectoryInfo 物件
取得資料夾屬性的 FileAttributes 物件
建立日期
存取日期
修改日期
7-2-3 資料夾的處理-建立物件

System.IO名稱空間的資料夾操作類別分
為Directory類別方法和DirectoryInfo類
別的實例方法兩種。在本節主要說明
DirectoryInfo類別的實例方法與屬性來處
理資料夾,如下所示:
Dim dirInfo As DirectoryInfo = New
DirectoryInfo(path)

程式碼使用建構子建立DirectoryInfo物件,
其參數是實際路徑,然後可以使用相關方
法與屬性來處理資料夾。
7-2-3 資料夾的處理-DirectoryInfo物
件方法與屬性
方法
說明
Create()
建立資料夾
CreateSubdirectory(String)
建立子資料夾,參數是子資料夾名稱字串
Delete(True)
刪除資料夾,參數決定是否刪除子資料夾,True 是
刪除子資料夾
MoveTo(String)
移動資料夾到參數的資料夾名稱字串
屬性
Exists
說明
檢查資料夾是否存在,True 表示存在,False 表示不
存在
7-2-4 顯示檔案清單和資訊-顯示資
料夾的檔案清單

在建立DirectoryInfo物件後,就可以使用
GetFiles()方法取得其下的檔案清單陣列,如下
所示:
Dim subFiles() As FileInfo = dInfo.GetFiles()

程式碼取得FileInfo檔案物件陣列subFiles後,
可以使用For Each迴路取得其中的FileInfo檔案
物件,如下所示:
Dim subFile As FileInfo
For Each subFile In subFiles
s &= "<tr><td>" & subFile.Name & "</td>"
Next
7-2-4 顯示檔案清單和資訊-FileInfo
類別的屬性1

檔案可以使用其路徑來建立FileInfo檔案物
件,如下所示:
Dim fInfo As FileInfo = New FileInfo(path)

程式碼使用New關鍵字的建構子來建立物
件,參數是檔案的實際路徑。
7-2-4 顯示檔案清單和資訊-FileInfo
類別的屬性2

在建立好物件後,即可使用相關屬性來取得檔案
資訊,如下表所示:
屬性
Name
FullName
Extension
Directory
DirectoryName
Attributes
CreationTime
LastAccessTime
LastWriteTime
Length
說明
檔案名稱
檔案全名,包含檔案路徑
檔案副檔名
取得父資料夾的 DirectoryInfo 物件
父資料夾的完整路徑
取得檔案屬性的 FileAttributes 物件
建立日期
存取日期
修改日期
檔案大小
7-2-5 檔案處理-建立物件


Web伺服器的檔案處理是指刪除、複製、移動伺
服器的檔案和檢查檔案是否存在等操作。
在System.IO名稱空間類別的檔案操作方法和資
料夾相似,分為File類別的類別方法和FileInfo類
別的實例方法,本節主要說明FileInfo類別的實
例方法,如下所示:
Dim fileInfo As FileInfo = New FileInfo(path)

上述程式碼的參數path是檔案的實際路徑,在建
立好FileInfo物件後,就可以使用相關方法執行
檔案操作。
7-2-5 檔案處理-FileInfo物件方法與
屬性
方法
Create()
Delete()
MoveTo(String)
CopyTo(String, True)
說明
建立 FileStream 的檔案串流
刪除檔案
移動檔案至參數 String 字串的路徑
複製檔案到參數 String 字串的路徑,第 2 個參數
為 True,表示覆寫存在檔案,False 為不覆寫
屬性
Exists
說明
檢查檔案是否存在
7-3 文字檔案讀寫、搜尋和取代




7-3-1
7-3-2
7-3-3
7-3-4
文字檔案讀寫的基礎
文字檔案的讀寫函數
文字檔案的搜尋和取代
文字檔案內容的編碼
7-3-1 文字檔案讀寫的基礎-說明

串流(Stream)觀念最早是使用在Unix作業系
統,串流模型如同水管的水流一般,當程式開啟
一個來源的輸入串流(例如:檔案、記憶體和緩
衝區等),ASP.NET程式可以從輸入串流依序讀
取資料,如下圖所示:
7-3-1 文字檔案讀寫的基礎步驟一:開啟或建立文字檔案的串流物件

首先使用FileInfo類別的CreateText()方法建立
全新的文字檔案,如下所示:
Dim sw As StreamWriter = fileInfo.CreateText()

對於存在的文字檔案,我們可以使用
StreamReader類別開啟讀取檔案,如下所示:
Dim sr As StreamReader = _
New StreamReader(path)

如果開啟檔案是用來寫入資料,就是使用
StreamWrite類別,如下所示:
Dim sw As StreamWriter = _
New StreamWriter(path)
7-3-1 文字檔案讀寫的基礎步驟二:執行檔案串流內容的讀寫

在建立StreamReader和StreamWriter串流物件後,就
可以使用相關方法來執行讀寫。StreamWriter類別的相
關方法,如下表所示:
方法
Write(String)
WriteLine(String)

說明
將參數 String 字串寫入檔案
繼承自 TextWriter 類別的方法,可以寫入參數 String 字
串且在最後加上換行字元
StreamReader類別的相關方法,如下表所示:
方法
說明
Read()
讀取下一個字元
ReadLine()
讀取一行,但不含換行字元
ReadToEnd()
從目前位置讀取到檔尾,讀取剩下整個文字檔內容
Peek()
檢查下一個字元什麼,但是並沒有讀取,值-1 表示到達檔案
串流的結尾
7-3-1 文字檔案讀寫的基礎步驟三:關閉檔案串流

在處理完文字檔案的讀寫後,就可以將緩
衝區資料寫入和關閉檔案串流,如下所示:
sw.Flush()
sw.Close()

Close()方法可以關閉StreamWriter或
StreamReader串流物件,Flush()方法是
StreamWriter類別繼承自TextWriter類別
的方法,可以清除緩衝區資料,強迫將緩
衝區資料寫入檔案。
7-3-2 文字檔案的讀寫函數程序createTextFile()

程序createTextFile()是使用FileInfo物件的
CreateText()方法來建立文字檔案,如下所示:
Sub createTextFile(file As String)
Dim path As String = Server.Mappath(file)
Dim fileInfo As FileInfo = New FileInfo(path)
If fileInfo.Exists = False Then
Dim sw As StreamWriter = _
fileInfo.CreateText()
sw.Close()
End If
End Sub
7-3-2 文字檔案的讀寫函數函數readTextFile()

函數readTextFile()的傳回值是檔案全部內容字
串,如下所示:
Function readTextFile(file As String) As String
Dim path As String = Server.Mappath(file)
Dim sr As StreamReader = New
StreamReader(path)
Dim fileContent As String = sr.ReadToEnd()
sr.Close()
Return fileContent
End Function
7-3-2 文字檔案的讀寫函數程序saveTextFile()

程序saveTextFile()可以將第2個參數的字串寫入
第1個參數的檔案,此程序會覆寫文字檔案內容,
如下所示:
Sub saveTextFile(file As String, textLine As
String)
Dim path As String = Server.Mappath(file)
Dim sw As StreamWriter = _
New StreamWriter(path)
sw.WriteLine(textLine)
sw.Flush()
sw.Close()
End Sub
7-3-2 文字檔案的讀寫函數程序appendTextFile()

程序saveTextFile()改為FileInfo物件的
AppendText()方法來開啟StreamWriter寫入串
流,寫入字串是新增在檔尾,並不會覆寫原來內
容,如下所示:
Sub appendTextFile(file As String, appendLine As
String)
Dim path As String = Server.Mappath(file)
Dim fileInfo As FileInfo = New FileInfo(path)
Dim sw As StreamWriter = _
fileInfo.AppendText()
sw.WriteLine(appendLine)
sw.Flush()
sw.Close()
End Sub
7-3-3 文字檔案的搜尋和取代函數searchTextFile()

函數searchTextFile()可以在檔案搜尋指定字串,傳入參數依序為搜
尋文字檔案和關鍵字,傳回值True表示找到,如下所示:
Function searchTextFile(file, searchText) As Boolean
Dim isFound As Boolean = False
Dim path As String = Server.Mappath(file)
Dim sr As StreamReader = New
StreamReader(path)
Dim fileContent As String = sr.ReadToEnd()
If fileContent.IndexOf(searchText) >= 0 Then
isFound = True
End If
sr.Close()
Return isFound
End Function
7-3-3 文字檔案的搜尋和取代函數replaceTextFile()1
函數replaceTextFile()可以搜尋指定字串且取代成另一
個字串,傳入參數依序為搜尋文字檔案、關鍵字和取代字
串,可以傳回取代次數,如下所示:
Function replaceTextFile(file,target,repStr) As
Integer
Dim fileContent As String = ""
Dim textLine, strLeft, strRight As String
Dim pos, begin, count As Integer
Dim path As String = Server.Mappath(file)
Dim sr As StreamReader = New
StreamReader(path)
count = 0
Do
textLine = sr.ReadLine()
pos = 0

7-3-3 文字檔案的搜尋和取代函數replaceTextFile()2
Do
begin = pos
pos = textLine.IndexOf(target, begin)
If pos >= 0 Then
If pos = 0 Then
strLeft = ""
Else
strLeft = textLine.Substring(begin, pos)
End If
strRight=textLine.Substring( _
pos+target.Length)
textLine = strLeft & repStr & strRight
count = count + 1
Else
7-3-3 文字檔案的搜尋和取代函數replaceTextFile()3
fileContent = fileContent & textLine & _
Convert.ToChar(13) & _
Convert.ToChar(10)
End If
Loop While pos >= 0
Loop Until sr.Peek() = -1
sr.Close()
Dim sw As StreamWriter = New
StreamWriter(path)
sw.WriteLine(fileContent)
sw.Flush()
sw.Close()
Return isFound
End Function
7-3-4 文字檔案內容的編碼-寫入

一般來說,文字檔案內容都是使用系統預設的
ANSI編碼(即使用Encoding.Default),如果
文字檔案內容不是使用系統的標準編碼,我們可
以在開啟StreamWriter串流物件時,指定檔案
編碼,如下所示:
Dim sw As StreamWriter = New StreamWriter( _
path, True, Encoding.UTF7)

程式碼在開啟StreamWriter串流時指定編碼,
第2個參數True表示開啟檔案是新增至檔尾,如
為False表示覆寫存在內容,最後一個參數是編碼,
以此例為UTF-7。
7-3-4 文字檔案內容的編碼-讀取

如果檔案內容不是標準編碼,我們在開啟
StreamReader串流物件讀取檔案時,也
需要指定編碼,才能正確讀取檔案內容,
如下所示:
Dim sr As StreamReader = _
New StreamReader( _
path, Encoding.UTF7)

程式碼的第2個參數是使用的編碼。
7-4 二進位檔案的處理-開啟

System.IO名稱空間的類別可以將檔案內容開啟
成為串流,除了文字檔案外,一樣可以處理二進
位檔案。以網頁來說,二進位檔案主要是指圖片
檔案,換句話說,我們可以建立FileStream類別
的串流物件來開啟圖片檔案,如下所示:
Dim objStream As FileStream
objStream = File.Open(path, FileMode.Open)

程式碼使用File類別Open()方法開啟FileStream
串流。另一種方法是使用建構子,如下所示:
Dim objStream As FileStream
objStream = New FileStream(path, _
FileMode.Open)
7-4 二進位檔案的處理-讀取

在開啟二進位檔案的FileStream串流後,因為內
容是二進位資料,所以需要建立Byte資料型態陣
列的緩衝區來存放,如下所示:
Dim imageBuffer(objStream.Length) As Byte

程式碼宣告長度為檔案串流尺寸的緩衝區,接下
來,就可以使用Read()方法讀取檔案內容,如下
所示:
objStream.Read(imageBuffer, 0, _
objStream.Length)
7-5 XML文件的處理




7-5-1
7-5-2
7-5-3
7-5-4
.NET Framework與XML
ASP.NET載入與瀏覽XML文件
ASP.NET與XSLT
ASP.NET與XPath
7-5-1 .NET Framework與XML-名稱
空間

.NET Framework內建支援XML相關技術,
其相關名稱空間的說明,如下所示:
• System.Xml:提供基本XML功能的類別和方
法,包含DOM和XMLReader(即微軟版的
SAX)的相關類別與方法。
• System.Xml.Xsl:提供XSLT轉換XML文件的
相關類別與方法。
• System.Xml.XPath:提供XPath相關的類別
與方法。
• System.Xml.Schema:提供XML Schema
驗證的相關類別與方法。
7-5-1 .NET Framework與XML-匯入
名稱空間

在ASP.NET程式使用.NET Framework的
XML時,需要匯入上述名稱空間,例如:
匯入System.Xml名稱空間,如下所示:
<%@ Import Namespace="System.Xml" %>
7-5-1 .NET Framework與XMLDOM節點類別

.NET Framwork的DOM支援Level 1和
Level 2核心模組,主要的DOM節點類別,
如下表所示:
節點類別
XmlDocument
XmlNode
XmlNodeList
XmlNamedNodeMap
XmlElement
XmlText
說明
樹狀結構表示整份 XML 文件
節點物件,新增、刪除和修改節點的物件
節點清單物件,也就是子樹
元素節點的屬性集合
XML 元素節點
文字節點
7-5-2 ASP.NET載入與瀏覽XML文件
-載入XML文件

ASP.NET程式是使用XmlDocument物件
來載入 XML 文件,如下所示:
Dim xmlDom As XmlDocument
xmlDom = New XmlDocument()
xmlDom.Load( _
Server.MapPath("Ch7-5.xml"))

程式碼在建立XmlDocument物件後,使
用Load()方法來載入XML文件。
7-5-2 ASP.NET載入與瀏覽XML文件
-瀏覽XML文件1

當ASP.NET程式載入XML文件建立
XmlDocument物件後,就可以使用
documentElement屬性取得根節點物件,
如下所示:
Dim node, nd As XmlNode
node = xmlDom.DocumentElement
book = node.FirstChild

程式碼使用FirstChild屬性取得第1個book
子元素。
7-5-2 ASP.NET載入與瀏覽XML文件
-瀏覽XML文件2

同樣的,我們可以使用HasChildNodes屬性檢查
是否有子節點,ChildNodes屬性取得所有子節點
的子樹,如下所示:
For Each nd In book.ChildNodes
Response.Write("<tr><td>" & _
nd.Name & "</td>")
Response.Write("<td>" & _
nd.InnerText & "</td></tr>")
Next

屬性清單的處理是使用XmlNamedNodeMap物
件,如下所示:
Dim atts As XmlNamedNodeMap
atts = book.Attributes
7-5-2 ASP.NET載入與瀏覽XML文件
-XmlDocument物件的屬性

XmlDocument物件的相關屬性說明,如
下表所示:
屬性
DocumentElement
FirstChild
LastChild
HasChildNodes
ChildNodes
Attributes
說明
取得根節點
第 1 個子節點
最後 1 個子節點
檢查是否有子節點,True 為有,False 為沒有
取得所有子節點的子樹
取得屬性清單的 XmlNamedNodeMap 物件
7-5-3 ASP.NET與XSLT-Xml伺服端
控制項
在伺服端可以使用XML文件配合XSLT文件,將
XML文件輸出成HTML文件。
 ASP.NET提供Xml伺服端控制項來顯示XML文件,
或是XML與XSLT文件的轉換結果,如下所示:
<asp:Xml Id="myxml" Runat="server"/>
 標籤是名為myxml的Xml伺服端控制項,其相關
屬性可以指定使用的XML或XSLT文件。

7-5-3 ASP.NET與XSLT-Xml伺服端
控制項屬性

Xml伺服端控制項相關屬性可以指定使用的
XML或XSLT文件,如下表所示:
屬性
DocumentSource
TransformSource
Document
Transform
說明
XML 文件的路徑
XSLT 文件的路徑
使用的 XmlDocument 物件
使用的 XslTransform 物件
7-5-3 ASP.NET與XSLT-執行XSLT轉
換1


在ASP.NET程式匯入System.Xml和
System.Xml.Xsl名稱空間後,就可以建立
XmlDocument和XslTransform物件,然後配合
Xml控制項來顯示轉換結果。
首先建立XmlDocument物件來載入XML文件,
如下所示:
Dim doc As XmlDocument = New XmlDocument()
doc.Load(Server.MapPath("Ch7-5.xml"))

接著載入XSLT文件建立XslTransform物件,如
下所示:
Dim trans As XslTransform = new XslTransform()
trans.Load(Server.MapPath("Ch7-5.xslt"))
7-5-3 ASP.NET與XSLT-執行XSLT轉
換2

最後我們可以指定XML控制項的
Document和Transform屬性,如下所示:
myxml.Document = doc
myxml.Transform = trans

程式碼指定相關屬性為XmlDocument和
XslTransform物件,就可以在控制項執行
XSLT轉換輸出成HTML文件。
7-5-4 ASP.NET與XPath1
XPath(XML Path Language)語言屬於第四
代程式語言,這是一種宣告語言來在XML文件中
走訪和標示節點位置,我們可以使用XPath語言
來描述指定XML元素或屬性的位置,如同
Windows作業系統硬碟資料夾的檔案路徑,如下
所示:
node = xmlDom.SelectSingleNode( _
"/library/book[2]/title")
 上述程式碼的SelectSingleNode()方法參數就是
XPath路徑字串,可以找到第2本圖書的title元素。

7-5-4 ASP.NET與XPath2

SelectNodes()可以取得XmlNodeList的
節點集合,如下所示:
nodes = xmlDom.SelectNodes( _
"/library/book[@sales='N']")
For Each node In nodes
Response.Write(node.Name & " - ")
Response.Write(node.InnerText & "<br>")
Next