宝哥软件园

ASP.NET下载文件时会根据MIME类型自动判断保存文件的扩展名

编辑:宝哥软件园 来源:互联网 时间:2021-10-25

导读用WebClient下载远程资源时,我们经常会遇到这样一个网站:http://www.uushare.com/filedownload?用户=iceseeid=2205188http://www.guaishow.com/u/luanfujie/g9675/we不知道这个Url具体代表的是一个网页还是某个类型的文件。虽然有些URL有扩展名,但它们可能是错误的扩展名,例如用jpg扩展名标记gif文件。如果不能正确判断下载源的文件类型,就无法以正确的文件格式保存,会给后续操作和手动读取带来麻烦。幸运的是,WebRequest可以给出下载源的MIME信息,这允许我们确定文件的真实格式,并确定最终的存储扩展名。(什么是MIME?建立MIME映射字典我们需要做的第一件事是建立MIME类型到它们相应扩展的映射字典。我从网上找到一个MIME类型的列表,通过正则表达式转换成程序代码,粘贴到程序中:image

这个正则表达式转换的代码量非常大。需要注意的是,有很多MIME类型相同但扩展名不同的数据,所以我们在将它们添加到字典中时,忽略了不必要的记录。例如,如果三个突出显示的项目是audio/x-aiff类型,则最后两个扩展不会添加到字典中,也不会用于后续操作。如果您认为某些类型添加的对应扩展不是最常见的对应类型,那么您必须手动调整代码。(这发生在下面,例如,text/html对应于dhtml扩展名,image/jpeg对应于jpe扩展名。)字典建立后,可以通过这样一种方法获得MIME类型对应的扩展名:string获得对应的扩展名(string content type){ foreach(var f in MIME . keys){ if(content type。tolower()。(f)=0)的索引返回模拟[f];}返回null}这里使用IndexOf方法的原因是传入的ContentType可能还包含其他信息,例如编码格式。前言:在网上看到有人抱怨WebClient在下载网页时容易出现乱码字符,网页的编码格式很难读懂。事实上,WebRequest的ContentType包含MIME和编码格式信息:image

生成下载文件路径现在使用上述方法,我们可以通过MIME类型来确定文件扩展名。现在,我们将编写一个生成下载文件路径的方法。它的功能是分析文件的源Url,并使用其文件名作为下载文件的文件名。如果其Url不包含文件名部分(以域名或目录的形式),其目录名将用作下载文件的文件名。根据要用作下载文件文件名的传入MIME类型,自动确定并替换Url中的原始扩展名(如果有)。判断传入存储目录中是否已经存在与下载文件同名的文件,如果存在,则重命名,直到没有同名文件。功能太多,不适合举例,但还是很实用的,在这里顺便分享一下。代码:复制代码如下: string生成下载文件存储路径(string存储目录,uri uri,string ContentType) {varex=获取对应的扩展名(content type);字符串up=null字符串upne=nullIf (Uri。LocalPath=='/') {//处理Url是域名up=upne=Uri的情况。主持人;} else { if(uri . local path . end swith('/')){//处理Url是目录up=uri.localpath.substring (0,uri.localpath.length-1)的情况;upne=路径。GetFileName(向上);} else {//处理通用Url up=Uri。LocalPathupne=路径。getfilename不带text extension(向上);} } var name=string。IsNullOrEmpty(ex)?路径。GetFileName(向上): upne .“”ex;Var fn=路径。组合(存储目录、名称);var x=1;while(file . exists(fn)){ fn=path.combine(存储目录,path . getfilename with extension(name)'(' x ')' path . getextension(name));}返回fn;}为了验证其效果,我们通过一个单元测试进行评估:复制代码如下: [TestMethod] public void文件名生成测试(){ var d=@ ' c : users public downloads ';//gif格式文件,通常下载assert . are equal(@ ' c : users public downloads 35 ad 5275 ed 17904 d4a 2d 40 F3 da ae8b . gif ',并生成下载文件的存储路径(d,newuri ('/upload/2009-11/2009)。//url中的扩展名是gif,但MIME类型实际上是image/jpeg的资源。下载后的扩展名是jpe,因为字典MimeDic中存储的对应扩展名是jpe。assert . are equal(@ ' c : users public downloads 35 ad 5275 ed 17904 d4a 2d 40 F3 da ae8b . jpe ',并生成下载文件的存储路径(d,new uri('/upload/2009-11/200911223100)。//带有参数的网页url。下载后的扩展名是dhtml,因为字典MimeDic中存储的对应扩展名是dhtml。建立. areequal(@ ' c : users public downloads file download . DHTML ',并生成下载文件的存储路径(d,new uri(' http://www.uushare.com/filedownload?用户=iceseeid=2205188 '),' text/html ');//网页url,采用目录的形式,没有确切的文件名。

断言AreEqual(@ ' c : 用户公共下载g9675.dhtml ',生成下载文件存放路径(d)新Uri(' http://www。瓜伊秀。com/u/luanfujie/g 9675/'),' text/html ');//域名形式断言AreEqual(@ ' c : 用户公共下载www.g.cn.dhtml ',生成下载文件存放路径(d,new Uri('http://www.g.cn/'),' text/html ');断言AreEqual(@ ' c : 用户公共下载g.cn.dhtml ',生成下载文件存放路径(d,new Uri('http://g.cn ',' text/html ');} 文件下载万事俱备,只欠东风了,让我们来完成下载方法:复制代码代码如下: ///summary ///下载文件到指定目录,并返回下载后存放的文件路径////summary ///param name='Uri '网址/param ///param name='存放目录'存放目录,如果该目录中已存在与待下载文件同名的文件,那么将自动重命名/param /返回下载文件存放的文件路径/返回公共字符串下载文件(Uri,Uri字符串存放目录){ var q=WebRequest .创建(Uri).GetResponse();var s=q . GetResponseStream();var b=新的BinaryReadervar文件=生成下载文件存放路径(存放目录,Uri,q . ContentType);FileStream fs=新的FileStream(文件,文件模式。创建,文件访问。写);fs .write(b . ReadBytes((int)q .内容长度),0,(int)q .内容长度);fs .close();关闭();关闭();返回文件;} 代码很简单,就不多说了,我们来完成最后的测试:复制代码代码如下:[测试方法]公共无效文件下载测试(){ var d=@ ' C: 用户公共下载;//首次下载断言AreEqual(@ ' c : 用户公共下载文件下载。' dhtml ',下载文件(新Uri(' http://www .uushare。com/文件下载?user=iceseeid=2205188 ')、d));//第二次下载,遇到同名文件,自动重命名断言AreEqual(@ ' c : 用户公共下载文件下载(1)。'' dhtml ',下载文件(新Uri(' http://www .uushare。com/文件下载?user=iceseeid=2205188 ')、d));//下载一个原本是可交换的图像格式类型的文件断言AreEqual(@ ' c : 用户公共下载2naqyw8.gif ',下载文件(新Uri(' http://i38。连续型。com/2 naqyw 8。jpg ')、d);} 结语相较没用过而言,WebRequest拥有更好的可控性,在没用过无解的时候,就尝试让请求上场吧。范例源代码和本文的波段移相器(同x波段移相器)版本打包下载http://xiazai.jb51.net/200911/yuanma/asp.net_mime_down.rar转载http://skyd.cnblogs.com/

更多资讯
游戏推荐
更多+