c#共享磁盘附件下载到本地,IIS访问共享文件,下载到本地
功能背景:项目上有个附件需要通过共享磁盘进行下载,折腾了一天,下面结合网上的一些说法,做一些总结
这里描述的都是以两台电脑作为服务器
问题:1、使用共享磁盘下载附件会出现iis权限问题
2、中间遇到坑:使用vs直接运行操作普通磁盘一样操作可以下载成功,但是把项目部署到iis上面就访问不了。(最后有做解释)
环境说明:
(192.168.0.111)A, (192.168.0.105)B
A服务器:文件服务器,提供共享磁盘H(文件夹类似)。
B服务器,部署需要下载的附件的程序,使用A提供的H共享磁盘。
创建共享文件
1、要共享出来的文件,右击属性:共享,加入用户权限。在A服务器建立共享磁盘H
2、打开应用程序部署的服务器 B:192.168.0.105,打开我的电脑,右键:映射网络驱动器
添加完之后在网络就会出现,这里需要填写A服务器的用户名密码
看到的磁盘z:就是共享过来的磁盘,建立一个控制台程序或者Mvc的项目使用vs直接运行是可以当作本地磁盘运行的,如果不用部署到iis的话到这一步就可以了
对应的代码:下面是一个文件的复制,操作和普通磁盘一样,没有区别
/// <summary>
/// 大文件多次复制文件 true:复制成功 false:复制失败
/// </summary>
/// <param name="soucrePath">原始文件路径</param>
/// <param name="targetPath">复制目标文件路径</param>
/// <returns></returns>
public bool CopyFile(string soucrePath, string targetPath)
{
try
{
//读取复制文件流
using (FileStream fsRead = new FileStream(soucrePath, FileMode.Open, FileAccess.Read))
{
//写入文件复制流
using (FileStream fsWrite = new FileStream(targetPath, FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] buffer = new byte[1024 * 1024 * 2]; //每次读取2M
//可能文件比较大,要循环读取,每次读取2M
while (true)
{
//每次读取的数据 n:是每次读取到的实际数据大小
int n = fsRead.Read(buffer, 0, buffer.Count());
//如果n=0说明读取的数据为空,已经读取到最后了,跳出循环
if (n == 0)
{
break;
}
//写入每次读取的实际数据大小
fsWrite.Write(buffer, 0, n);
}
}
}
return true;
}
catch (System.Exception ex)
{
return false;
}
}
方法调用
/// <summary>
/// vs直接运行可以复制文件
/// </summary>
/// <param name="sharepath">共享磁盘的路径</param>
/// <param name="targetpath">需要复制的路径</param>
public void CopyFileDown(string sharepath,string targetpath)
{
if (Directory.Exists(@"z:"))
{
// bool b = this.CopyFile(@"z:\aa.docx", @"d:\aa.docx");//这是一个写死的路径 z:盘就是共享磁盘
this.CopyFile(sharepath, targetpath);
//直接下载返回客户端
string pathFile = sharepath;
string fileName = pathFile.Substring(pathFile.LastIndexOf('\\') + 1);
fileName = HttpUtility.UrlDecode(fileName);
System.IO.FileInfo fileInfo = new FileInfo(pathFile);
// bool a= System.IO.File.Exists(pathFile);
if (fileInfo.Exists)
{
Response.ClearHeaders();
Response.Clear();
Response.HeaderEncoding = System.Text.Encoding.GetEncoding("GB2312");
Response.AppendHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(fileName));
Response.AddHeader("Content-Type", "application/x-zip-compressed");
Response.ContentType = "application/x-zip-compressed";
using (System.IO.FileStream fs = System.IO.File.OpenRead(pathFile))
{
Byte[] buf = new Byte[fs.Length];
fs.Read(buf, 0, (int)fs.Length);
Response.BinaryWrite(buf);
fs.Close();
Response.End();
}
Response.End();
}
}
}
提醒下,如果B的程序是跑的IIS Express,直接当作本地磁盘Z:没问题,但是使用IIS,就访问不到。不信你试试,下面讲解是让IIS也能访问到的全过程。下面的内容是关于需要部署到IIS进行访问
1、首先把你写好的项目部署到IIS站点,我这里用的是一个mvc的项目,使用其他的也可以
2、添加虚拟目录虚拟目录; 右击B服务器的当前站点,添加虚拟目录---连接为---特定用户:具体配置如下
2、需要检查连接是否成功
这里需要注意的是,A文件共享服务器需要创建cs用户名,B应用服务器也要创建同样的用户名cs。谨记,必须!!
这里也必须是用图片服务器共享出来的用户,制定为特定用户。
C#程序是访问共享文件展示
前端调用
<a href="/home/FileDown">附件下载</a>
public void FileDown()
{
var path = @"\FileShare\aa.docx";
path = Server.MapPath(path); //由于FileShare是A服务器的共享文件,这里解析的路径为:\\192.168.0.111\FileShare\aa.docx"
System.IO.FileInfo fileInfo = new FileInfo(path);
if (fileInfo.Exists)//检查文件是否存在
{
//如果文件存在这里面就可以当作本地磁盘进行操作了
downs(path);
}
}
最后重复说明下:如果出现vs打开可以下载,部署到iis无法下载的情况需要添加以下配置,也是结合多个前辈们的经验
解决开头的问题2
(1) 请在的WEB.config中添加如下代码:
<system.web>
<identity impersonate="true" userName="cs" password="对应cs的密码" />
</system.web>
(2) 然后在你的A服务器和B服务器上都创建该用户cs和密码,保证和Web.config中一致
(3) 在A服务器中建立一个目录如H,设置该目录为网络H,并设置可读写权限给cs用户,切记。
(4) 将原本程序池的运行标识还恢复到"网络服务"
(5) 重启iis
至此,IIS访问共享文件的问题已经全部解决完成,你也可以搭建访问下试试。如果有问题,或有更多的解决方案分享