對於Web程序,使用一臺服務器的時候,客戶端上傳的文件通常也都是存儲在這臺服務器上。但在集羣環境中就行不通了,若是每一個服務器都存儲本身接受到的文件,就亂套了,數據庫中明明有這個附件的記錄,卻找不到這個文件。因而,文件須要進行統一集中管理,並向集羣中的服務器提供統一的路徑。html
Network File System 簡稱NFS,用人話說叫共享文件夾,能夠實現分佈式存儲文件。只須要在文件服務器上共享文件夾,並指定相應帳號的權限,並給Web服務器設置能夠訪問共享文件夾的帳號和密碼,web服務器就能夠像操做本地文件同樣操做文件服務器上的文件了。NFS下的文件訪問路徑有固定的格式,稱爲UNC(Universal Naming Convention),以「\\」開頭。web
要以UNC的方式訪問NFS下的文件,須要用到windows提供的兩個API:WNetAddConnection2 和 WNetCancelConnection2。WNetAddConnection2可使用指定的帳號和密碼建立一個UNC的鏈接,而後程序能夠直接訪問該UNC下文件。數據庫
首先建立類FileServerConnection,用於管理鏈接,具體代碼以下:windows
public class FileServerConnection { private string uncName; private string username; private string password; /// <summary> /// 構造器 /// </summary> /// <param name="uncName">完整的UNC路徑</param> /// <param name="username">訪問共享鏈接的用戶名</param> /// <param name="password">訪問共享鏈接的密碼</param> public FileServerConnection(string uncName, string username, string password) { this.uncName = uncName; this.username = username; this.password = password; } /// <summary> /// 鏈接文件服務器 /// </summary> public void Connect() { var netResource = new NetResource { Scope = ResourceScope.GlobalNetwork, ResourceType = ResourceType.Disk, DisplayType = ResourceDisplayType.Share, RemoteName = this.uncName.TrimEnd('\\') }; var result = WNetAddConnection2(netResource, password, username, 0); if (result != 0) throw new Win32Exception(result); } /// <summary> /// 釋放鏈接 /// </summary> public void Disconnect() { WNetCancelConnection2(this.uncName, 0, true); } [DllImport("mpr.dll")] private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); private static extern int WNetCancelConnection2(string name, int flags, bool force); }
FileServerConnection中所用到的幾個結構體代碼以下:安全
[StructLayout(LayoutKind.Sequential)] public class NetResource { public ResourceScope Scope; public ResourceType ResourceType; public ResourceDisplayType DisplayType; public int Usage; public string LocalName; public string RemoteName; public string Comment; public string Provider; } public enum ResourceScope { Connected = 1, GlobalNetwork, Remembered, Recent, Context } ; public enum ResourceType { Any = 0, Disk = 1, Print = 2, Reserved = 8, } public enum ResourceDisplayType { Generic = 0x0, Domain = 0x01, Server = 0x02, Share = 0x03, File = 0x04, Group = 0x05, Network = 0x06, Root = 0x07, Shareadmin = 0x08, Directory = 0x09, Tree = 0x0a, Ndscontainer = 0x0b }
而後在Web程序啓動的時候,只須要建立一個FileServerConnection的實例,而後調用它的Connect方法。爲了防止重複建立鏈接引起異常,能夠Connect以前先DisConnect。具體調用代碼以下: 服務器
fsConnection= new FileServerConnection (storeRootPath, username, password); fsConnection.Disconnect(); fsConnection.Connect();