SharePoint服務器端對象模型 之 訪問文件和文件夾(Part 3)

(三)遍歷

文件系統的遍歷是指按照文件夾的層級結構遍歷文檔庫、列表的文件夾和列表條目。遍歷主要有三種方式:(1)直接使用文件系統對象模型進行遍歷;(2)使用SPDocumentLibrary進行遍歷;(3)藉助SPQuery進行遍歷。

1、SPList的Items和Folders屬性

在介紹真正的遍歷之前,有必要先解釋一下這兩個重要的屬性。

這兩個屬性返回的都是SPListItemCollection類型,它們分別返回了列表中所有的普通條目(或文件),以及列表中的所有文件夾。不論這些條目、文件、文件夾在列表的層次結構中處於什麼位置,Items和Folders屬性都會獲得列表中的全部內容,而且是不分層次結構的。

因此,實際上這兩個屬性的使用頻率要比遍歷操作高得多(尤其是Items屬性)。當我們需要獲取列表中的所有普通條目或者文件的時候(一般我們不太關心文件夾本身),就需要使用Items屬性。這個屬性的存在使得在操作文檔庫的時候,要比操作磁盤的文件系統方便得多——可以直接得到文檔庫中任意層次下的所有文件!

順便提一下,Items和Folders合在一起,就是列表中所存儲的所有內容。在SharePoint的對象模型中,SPList有一個屬性是ItemCount,返回列表中所存儲的所有條目的數目,經常有人認爲這個屬性就是spList.Items.Count,其實不然。實際上,spList.ItemCount應該等於spList.Items.Count + spList.Folders.Count。

 

2、使用文件系統對象模型進行遍歷

與.NET中傳統的FileInfo/DirectoryInfo類似地,SPFile和SPFolder也有着明顯的層級結構,通過使用SPFolder的Files(SPFileCollection類型)和SubFolders(SPFolderCollection類型)可以直接按照文件夾的層級結構使用foreach等方法進行遞歸遍歷,在此不再做示例。

這種方式的便利雖然直觀而且簡單,但是有兩個不容忽視的問題:

(1) 這種方式僅適用於文檔庫,普通列表雖然可以有Folder,但是沒有File,無法直接進行遍歷;

(2) 使用這種方式遍歷的時候,需要執行的帳號有“瀏覽目錄”的權限(如圖2-10);但是在SharePoint內置的權限級別中,只有“參與討論”及以上的權限級別才包含這個權限,換句話說,對於網站的“讀者”或“查看者”,是無法正常執行使用這種方式進行遍歷的程序的。

image

 

3、使用SPDocumentLibrary進行遍歷

這種方法藉助了SPList的一個專門針對文檔庫設計的子類:SPDocumentLibrary。雖然該方法同樣只能應用於文檔庫,但是解決了直接使用文件系統對象模型遍歷的第二個問題,即權限問題。

SPDocumentLibrary作爲SPList的子類,提供了一個特殊的方法,叫做GetItemsInFolder——顧名思義,是用於獲取文檔庫的某個文件夾下的內容的。此外,SPDocumentLibrary還提供了另外一個比較有用的屬性,IsCatalog(bool類型),用於判斷一個文檔庫是否是網站的配置文檔庫(比如列表模板庫、網站模板庫、Web部件庫、母版頁庫等)。使用SPDocumentLibrary進行文檔庫遍歷的具體方法可以參看下面這個示例:

   1: static void GoThroughDocLib(SPDocumentLibrary doclib, 
   2:     SPFolder folder, int level)
   3: {
   4:   SPListItemCollection items =
   5:   doclib.GetItemsInFolder(doclib.DefaultView, folder);
   6:   if (items.Count == 0) return;
   7:  
   8:   foreach (SPListItem item in items)
   9:   {
  10:     for (int i = 0; i < level; i++) Console.Write("  ");
  11:     if (item.FileSystemObjectType == SPFileSystemObjectType.Folder)
  12:     {
  13:       Console.WriteLine("[{0}]", item.Name);
  14:       GoThroughDocLib(doclib, item.Folder, level + 1);
  15:     }
  16:     else
  17:       Console.WriteLine(item.File.Name);
  18:   }
  19: }
  20:  
  21: static void Main(string[] args)
  22: {
  23:   using(SPSite site = new SPSite("http://sp2010/book"))
  24:   {
  25:     using(SPWeb web = site.OpenWeb())
  26:     {
  27:       SPDocumentLibrary doclib = web.Lists["共享文檔"] as SPDocumentLibrary;
  28:       GoThroughDocLib(doclib, doclib.RootFolder, 0);
  29:     }
  30:   }
  31: }

在本示例程序中,就應用了交叉訪問的方法,在區分了一個條目是文件還是文件夾之後,使用了SPListItem的File屬性和Folder屬性獲取其文件對象和文件夾對象。實際上,item.File.Name和item.Name是一樣的。

 

4、使用SPQuery進行遍歷

上述方法解決了文件系統遍歷的權限問題,但是仍然只是侷限在文檔庫中。實際上,上面一種方法是SharePoint 2003時代遺留下來的方法,到了2007和2010時代,普通列表中也增加了文件夾的結構,因此也就衍生了新的遍歷方法——藉助SPQuery的遍歷。

SPQuery的主要作用是進行列表查詢——從類名上就可以看出這一點。在查詢的時候,可以通過其Folder屬性指定查詢範圍的文件夾。通過這一特性,我們可以不指定任何查詢條件,就相當於返回範圍內的所有內容了。使用這種方法可以在所有的列表中進行遍歷,自然也包括了文檔庫,下面是一個例子:

   1: static void GoThroughList(SPList list, SPFolder folder, int level)
   2: {
   3:   SPQuery query = new SPQuery();
   4:   query.Folder = folder;
   5:   SPListItemCollection items = list.GetItems(query);
   6:   if (items.Count == 0) return;
   7:  
   8:   foreach (SPListItem item in items)
   9:   {
  10:     for (int i = 0; i < level; i++) Console.Write("  ");
  11:     if (item.FileSystemObjectType == SPFileSystemObjectType.Folder)
  12:     {
  13:       Console.WriteLine("[{0}]", item.DisplayName);
  14:       GoThroughList(list, item.Folder, level + 1);
  15:     }
  16:     else
  17:       Console.WriteLine(item.DisplayName);
  18:   }
  19: }
  20:  
  21: static void Main(string[] args)
  22: {
  23:   using(SPSite site = new SPSite("http://sp2010/book"))
  24:   {
  25:     using(SPWeb web = site.OpenWeb())
  26:     {
  27:       SPList list = web.Lists["Chapters"];
  28:       GoThroughList(list, list.RootFolder, 0);
  29:     }
  30:   }
  31: }

本程序大體結構與使用SPDocumentLibrary進行遍歷的程序完全相同,只是使用的方法不同。關於SPQuery的使用,在後文還有更加詳細的講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章