从URL下载/stream文件 – asp.net

我需要stream式传输文件,这将导致在浏览器中作为提示保存。 问题是,该文件所在的目录是虚拟映射的,所以我无法使用Server.MapPath来确定它的实际位置。 该目录与网站不在同一个位置(或者甚至是在活箱上的物理服务器)。

我想要像下面的东西,但是这将允许我通过一个url,而不是一个服务器文件path。

我可能不得不从configuration的基本pathbuild立我的文件path,然后追加到path的其余部分,但希望我可以这样做,而不是。

var filePath = Server.MapPath(DOCUMENT_PATH); if (!File.Exists(filePath)) return; var fileInfo = new System.IO.FileInfo(filePath); Response.ContentType = "application/octet-stream"; Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath)); Response.AddHeader("Content-Length", fileInfo.Length.ToString()); Response.WriteFile(filePath); Response.End(); 

您可以使用HttpWebRequest获取文件并将其传输回客户端。 这可以让你获得一个URL的文件。 我发现的一个例子(但不记得在哪里给予信用)是

  //Create a stream for the file Stream stream = null; //This controls how many bytes to read at a time and send to the client int bytesToRead = 10000; // Buffer to read bytes in chunk size specified above byte[] buffer = new Byte[bytesToRead]; // The number of bytes read try { //Create a WebRequest to get the file HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url); //Create a response for this request HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse(); if (fileReq.ContentLength > 0) fileResp.ContentLength = fileReq.ContentLength; //Get the Stream returned from the response stream = fileResp.GetResponseStream(); // prepare the response to the client. resp is the client Response var resp = HttpContext.Current.Response; //Indicate the type of data being sent resp.ContentType = "application/octet-stream"; //Name the file resp.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); resp.AddHeader("Content-Length", fileResp.ContentLength.ToString()); int length; do { // Verify that the client is connected. if (resp.IsClientConnected) { // Read data into the buffer. length = stream.Read(buffer, 0, bytesToRead); // and write it out to the response's output stream resp.OutputStream.Write(buffer, 0, length); // Flush the data resp.Flush(); //Clear the buffer buffer = new Byte[bytesToRead]; } else { // cancel the download if client has disconnected length = -1; } } while (length > 0); //Repeat until no data is read } finally { if (stream != null) { //Close the input stream stream.Close(); } } 

我这样做很多,以为我可以添加一个更简单的答案。 我在这里设置了一个简单的课程,但是我每天晚上都会运行这个课程来收集我所关注公司的财务数据。

 class WebPage { public static string Get(string uri) { string results = "N/A"; try { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); StreamReader sr = new StreamReader(resp.GetResponseStream()); results = sr.ReadToEnd(); sr.Close(); } catch (Exception ex) { results = ex.Message; } return results; } } 

在这种情况下,我传递一个url,并以HTML的forms返回页面。 如果你想做一些不同于stream的东西,你可以很容易的改变它。

你这样使用它:

 string page = WebPage.Get("http://finance.yahoo.com/q?s=yhoo"); 

将url下载到字节并将字节转换为stream:

 using (var client = new WebClient()) { var content = client.DownloadData(url); using (var stream = new MemoryStream(content)) { ... } } 

2年后,我用达拉斯的答案,但我不得不将HttpWebRequest更改为FileWebRequest因为我链接到直接文件。 不知道这是否到处都是这种情况,但我想我会添加它。 另外,我删除了

var resp = Http.Current.Resonse

只要在引用resp地方使用Http.Current.Response

你可以尝试使用带有IISpath前缀的DirectoryEntry类:

 using(DirectoryEntry de = new DirectoryEntry("IIS://Localhost/w3svc/1/root" + DOCUMENT_PATH)) { filePath = de.Properties["Path"].Value; } if (!File.Exists(filePath)) return; var fileInfo = new System.IO.FileInfo(filePath); Response.ContentType = "application/octet-stream"; Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath)); Response.AddHeader("Content-Length", fileInfo.Length.ToString()); Response.WriteFile(filePath); Response.End();