文件传送常用的三种方式FTPEmail及网上邻居都在一定程度上实现了文件数据的交流但它们都主要面向点对点的传送无法实现一块空间资源互见的应用需求这种基于点对多的共享模式需要寻求另外的传输途径网络硬盘就是一种很好的解决方式
一常用传输方式及其在特定环境下面临的困难
我们经常有这样的应用需求通过网络交换公共数据文件以实现资源共享同时保护私有数据不被非法访问并使用简单直观的方式操作我们常用的文件传输FTPEmail邮件网上邻居都能实现文件的传送其中Ftp功能最为强大但使用起来却稍显复杂一大堆设置足以让许多人望而止步尤其用户数量不可预见时针对特殊需求用户的设置将更加繁琐Email是大家所熟悉的了但它的传送不仅需要你连入Internet而且它的安全性也是个问题在企业内部财务劳资等文件资料需通过这种方式交流不是好办法网上邻居是又一种传送文件的方法通过在本机上指定共享的Web文件夹并放置资源文件一定范围内的用户可以访问到这些文件然而这种方式使用的范围相当有限通常在同一个DNS段地址内的用户才能顺利访问其它尤其是Internet上的用户很难使用此外同Email类似它的使用也不直观很多时候你不得不在许多列表计算机上一层层展开搜索才有可能获取你想要的资源!
由此看来以上三种方式虽然在一定程度上实现了文件数据的交流但它们都主要面向点对点的传送(你只能被动地等对方放置数据而不能主动可视化地索取)无法实现一块空间资源互见的应用需求这种基于点对多的共享方式需要寻求另外的传输途径网络硬盘就是一种很好的解决方式
二网络硬盘的优势
网络硬盘(也称共享空间)是服务器上的一块硬盘空间在这里如果你具备足够的权限你可以对它随意操作就象使用你的本地计算机一样要知道这一切以Http的方式传输以Web的形式展现在所有用户面前通过浏览器这种熟悉的方式访问这样一块空间资源互见的共享模式得以实现!
此外网络硬盘界面在客户端运行它允许用户提交数据到服务器然后在指定的范围内管理这些信息这种处理模式大量使用在实际开发中尤其是在构建交互式网络文档管理系统方面网上考试系统文件传输系统新闻发布系统以及公司竞标系统等方面都有大量应用!
以下使用Aspnet(Visual C#语言实现)和Xml(可扩展标记语言)开发了这样的网络硬盘系统关于程序的开发细节及代码中使用的关键技术和难点都有详细的讲解参照这些说明你完全可以开发出自己的网络硬盘
三网络硬盘实现的功能
我们的网络硬盘实现了以下功能
查看文件夹内容
创建新文件夹同时可设置访问权限
文件夹间的跳转进入下一级返回上一级
上传文件到指定文件夹
下载文件到本机或在线查看文件内容
删除文件或文件夹
四开发细节及技术关键点
查看文件夹内容
程序一开始将进入指定的根文件夹(如\NetHard)这个文件夹下的内容将通过数据绑定控件(DataGrid)来列表显示包括以下方面类别(区别文件夹或文件)名称权限(是否允许进入文件夹?是否可以下载文件?)删除(是否允许删除文件或文件夹?)以及针对文件夹的创建者这里由于文件夹中内容动态变化(你不知道什么时候就有用户传送了文件或新建了文件夹或删除了它们)我们通过动态创建数据表DataTable来读取指定文件夹下的内容 然后作为数据源与显示控件DataGrid绑定这样数据的显示就总是适时的创建动态表的函数如下
public DataTable Bind(string fullFolderPath)//创建数据表读取文件夹内容
{
//以下是动态创建数据表的方法
DataTable dt=new DataTable();
DataRow dr;
//首先创建数据表结构
dtColumnsAdd(new DataColumn(typeSystemTypeGetType(SystemString)));//类型
dtColumnsAdd(new DataColumn(nameSystemTypeGetType(SystemString)));//名称
dtColumnsAdd(new DataColumn(actionSystemTypeGetType(SystemString)));//操作
dtColumnsAdd(new DataColumn(ownerSystemTypeGetType(SystemString)));//创建人
//为每一行填充数据
foreach(string d in DirectoryGetFileSystemEntries(fullFolderPath)){
dr=dtNewRow();//建新行
string[] parts=dSplit(new char[]{\\});
string txt=parts[partsLength];//取最后一部分的字符串它将可能是文件名或文件夹
dr[]=txt;//名称name
if(FileExists(d))//如果是文件
{
dr[]=文件;//类型type
int pos=currFullPathIndexOf(NetHard);
string relaUrl=currFullPathSubstring(pos);
string
url=http:///SharedSpace/+relaUrl+/+txt;//
为作者服务器地址你应该将它修改为你所在服务器地址
dr[]=<a href=+url+ target=_blank+>下载</a>;
}
else if(DirectoryExists(d)){//如果是文件夹
dr[]=文件夹;//type类型
string password=GetFolderPassword(d);//取得文件夹密码信息
int type=GetFolderLimitType(d);
if((password!=no)&&(type!=))
dr[]=<a
href=PasswordValidateaspx?path=+d+>密封</a>;//操作action
else
dr[]=<a href=Defaultaspx?path=+d+>进入</a>;//操作action
dr[]=GetFolderOwner(d);//取文件夹创建者名
}
else
ResponseWrite(<script>alert(无对象可绑定!)</script>);
dtRowsAdd(dr);//添加行
return dt;//返回数据表
}
}
这个方法取出指定文件夹下的内容分别处理如果是文件就显示下载链接指向服务器上文件的Url地址对文件夹需要视保护与否及保护类型进一步区别处理若进入受限则显示密封导入到密码验证页进入不受限时修改查询字符串显示进入链接指向初始显示页
创建新文件夹及设置访问权限
输入新文件夹名后你就可以在当前路径下创建新的文件夹Aspnet下远程创建新文件夹和在本地机操作完全一样非常的简单Net的IO名字空间提供了专门的类库Directory通过调用其方法就可以实现语句如下
DirectoryCreateDirectory(string directory)
其中字符串directory表示新建文件夹的完整路径这个方法默认向所有用户开放新文件夹的完全读写访问权限特殊地对网络硬盘共享根文件夹(程序中示例为NetHard文件夹你可以更改它)的创建你还可以手动进行对应地你需要手动设置以开放此文件夹的写入权限在IIS下你可以在internet信息服务下对该文件夹执行权限向导来设置访问权限
资源共享时应该考虑安全性这里你可以设置用户对该文件夹的访问权限通过设置密码你可以指定是否允许用户进入该文件夹是否允许删除该文件夹或者两者都禁止这样你可以保护自己的文件将它们独占访问或者限制在一个特定的范围内(这个范围的成员应该知道你的密码)这样产品研发部门可以共用一个文件夹财务部门也通过同样的方式共用另一个文件夹不属于这个部门的人员将限制访问当然这样的限制你也可以应用到单个文件上(这样的应用似乎不多程序未实现)
此外为了管理这些文件夹你需要保留它们的设置信息文件夹名位置受限操作类型密码及创建人等程序中将这些信息写入一Xml文件(此为folderxml文件)随后对文件夹的各种管理操作均通过读写该xml文件来进行以下方法就实现了新建文件夹时设置信息的存储
public void CreateXmlOrAddFrag(string xmlFullPathstring
folderFullPathstring ownerstring passwordint type){
XmlDocument xmlDoc=new XmlDocument();
string xml=;
string xmlNode=<character>;
xmlNode+=<fullPath>;
xmlNode+=folderFullPath;
xmlNode+=</fullPath>;
xmlNode+=<owner>;
xmlNode+=owner;
xmlNode+=</owner>;
xmlNode+=<password>;
xmlNode+=password;
xmlNode+=</password>;
xmlNode+=<type>;
xmlNode+=type;
xmlNode+=</type>;
xmlNode+=</character>;
if(!FileExists(xmlFullPath)){//不存在则创建xml存储文件
xml=<?xml version= encoding=gb?>;
xml+=<folder>;
xml+=xmlNode;
xml+=</folder>;
xmlDocLoadXml(xml);
xmlDocSave(xmlFullPath);//存储文件
}
else{//存在xml存储文件则添加新的文档片段
xmlDocLoad(xmlFullPath);
XmlDocumentFragment
docFrag=xmlDocCreateDocumentFragment();//文档片元素节点
docFragInnerXml=xmlNode;
XmlNode currNode=xmlDocDocumentElement;//获取文档根节澱
currNodeInsertBefore(docFragcurrNodeFirstChild);//插入文档段
xmlDocSave(xmlFullPath);//存储改变
}
}
其中参数fileFullPath是存储文件夹信息的xml文件路径folderFullPath是此新文件夹路径owner是创建人名password是密码type表示限制操作的类型(表示进入受限表示删除受限)在程序运行之初存储文件夹信息的folderxml文件可能尚不存在所以程序中首先判断这个文件是否存在不存在则动态创建这个文件这之后新建文件夹时将只需要添加文档片段这里对Xml文件的读写通过DOM(文档对象模型)来实现由于此处Xml文件不会太大这种方式不会对内存资源要求太高速度也会很快!
对文件及文件夹的操作
对文件的操作包括下载和删除两种在上面列表显示指定文件夹中内容时针对文件有这样的语句
dr[]=<a href=+url+ target=_blank+>下载</a>;//建立联接地址
其中url是指定文件对应的服务器路径 通过这样的链接将文件定位到服务器上的对应位置视文件格式的不同客户端可以下载文件到本机上也可以就在服务器上打开它
删除文件很简单Net的IO命名空间的File类库有这样的方法
FileDelete(string filename)其中filename为文件的完整路径
你需要注意的是文件的删除将不需要验证要防止文件被删除你需要依照下面的方式来进行(当然程序中为避免文件误删除提供了确认验证文件夹删除也一样!)
对文件夹的操作分为进入或者删除如果文件夹在创建时被设置进入受限或者删除受限用户在执行这样的操作时将被要求密码验证只有通过验证才能完成相应的操作这种方式保护了你的文件被非法访问或删除
相对文件的删除文件夹的删除程序要稍微复杂些Net的Directory类库提供的方法Delete()只能删除空文件夹这就需要我们首先清空文件夹中内容然后才能完成这一操作由于文件夹中还可能再包含有文件夹我们通过递归调用来实现这一操作
//删除文件夹的方法
public void DeleteFolder(string dir)
{
foreach(string d in DirectoryGetFileSystemEntries(dir))
{
if(FileExists(d))
FileDelete(d);//直接删除其中的文件
else
DeleteFolder(d);//递归删除子文件夹
}
DirectoryDelete(dir);//删除已空文件夹
}
其中参数dir是待删除文件夹的完整路径程序使用循环语句查找文件夹中的内容是文件则直接删除如果是文件夹则递归调用方法自身来删除子文件夹文件夹清空后再完成删除操作
文件上传
要实现网络硬盘的功能必须要有可供操作的文件这些文件来自于客户端的上传(当然服务器端也能提供这些文件但这不是网络硬盘的重点)过去我们实现文件的上传在Asp中通常是使用第一些文件上传组件比如Microsoft 的PostingAcceptor组件另外还有第三方提供的一些付费组件(不过说真的这些组件并不好用)那时候想要自己开发这样的文件上传组件相当繁琐而现在Net提供的类库HttpPostedFile和HttpFilesCollection可以很容易地访问上载到服务器的文件同时使开发人员控制文件上载过程其中的HttpPostedFile类封装已经上传到服务器的文件对象其方法和属性提供对每个文件的内容和属性的访问HttpFileCollection类则为多个HttpPostedFile对象提供一个容器用作保存上传给服务器的数据结构的类这样你就可以利用被传送的文件集合该文件集合可通过其Files属性从HttpRequest 对象访问一旦服务器接收了请求的整个内容该集合就可以访问这些内置的组件使得Aspnet中实现文件上传相当容易甚至只需要几行代码就可以了!关于Aspnet中实现文件上传的文章很多这里不做专门的阐述需要的话你可以参考那些文章这里只提示你需要注意以下几点
)客户端表单的编码类型Enctype 设置为multipart/formdata的MIME格式提交表单使用Http的post方法象下面这样
<form id=form method=post enctype=multipart/formdata/formdata
runat=server >
)HttpInputFile控件运行在服务器端设置runat=servertype=file 象下面这样
<INPUT id=fileUp type=file size= runat=server>
)要上传多个文件你可以布置多个HttpInputFile控件然后使用HttpRequestFiles来获取这些文件
环境配置文件Webconfig的处理
在中文状态下你可能需要将全球化设置编码由默认的Utf改为gb语句如下
<globalization
requestEncoding=gb
responseEncoding=gb
/>
同时Webconfig默认设置的的文件大小限制可能并不能满足你的需要你或许需要将限制尺度放大一些这通过修改参数maxRequestLength的值来实现如下所示
<! 设置可接受的最大字节数 >
<httpRuntime maxRequestLength=>
</httpRuntime>
随时跟蹤当前路径值
程序中的另一个关键点是关于当前路径的由于你总是需要在不同的文件夹之间跳转点击进入到达下一级文件夹点击上一级文件夹返回前一级文件夹而所有这些文件夹的内容都通过同一个页面(Defaultaspx)来显示这个显示页面被设置为始终显示当前文件夹下内容在你传送查询字符串来调用它时你需要在查询字符串中包含当前路径的完整表示这在程序中通过设置一个静态变量来实现public static string currFullPath= 当前路径发生改变时总是将这个路径值传送给这个静态标量
currFullPath=Request[path];这就使得这个静态变量始终存储着当前的路径值以这个静态变量为查询字符串调用显示页 ResponseRedirect(Defaultaspx?path=+currFullPath)就总能显示当前文件夹下的内容了!
参考资料
《Aspnet程序员参考手册》《XML高级编程》《C#高级编程》微软MSDN
运行环境
程序在Windows XP中文正式版.Net Frameworks 正式版Visual StudioNet中文正式版下调试通过在局域网(总部+多个异地子公司模式)上稳定运行