对于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();