如何在ASP.NET中检测文件下载何时完成?

时间:2011-01-13 02:14:30

标签: c# javascript asp.net

我有一个弹出窗口,显示“请等待文件下载时等待”。此弹出窗口还执行以下代码以启动文件下载。文件下载完成后,如何关闭弹出窗口?我需要一些方法来检测文件下载是否已经完成,所以我可以调用self.close()来关闭这个弹出窗口。

System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.ContentType = fileObject.ContentType;
System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Concat("attachment; filename=", fileObject.FileName));
System.Web.HttpContext.Current.Response.WriteFile(fileObject.FilePath);
Response.Flush();
Response.End();

6 个答案:

答案 0 :(得分:3)

一个想法:

如果您通过将chunk按块写入响应流来处理服务器端代码中的文件下载,那么您将知道文件何时完成下载。您只需将FileStream连接到响应流,按块发送数据块,然后在完成后重定向。这可以在弹出窗口中。

Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=bob.mp3");
Response.AppendHeader("content-length", "123456789");

确保在写出响应流时检查Response.IsClientConnected。

答案 1 :(得分:2)

有一种解决方案,您可以通过将文件作为较小的数据包传输来跟踪下载状态,并检查是否所有数据包都已传输。 解决方案不是我的,但你可以在这里找到它: File Download in ASP.NET and Tracking the Status of Success/Failure of Download

//Function for File Download in ASP.Net in C# and 
//Tracking the status of success/failure of Download.
private bool DownloadableProduct_Tracking()
{
//File Path and File Name
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";

System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

//Reads file as binary values
BinaryReader _BinaryReader = new BinaryReader(myFile);

//Ckeck whether user is eligible to download the file
if (IsEligibleUser())
{
//Check whether file exists in specified location
if (FileName.Exists)
{
    try
    {
    long startBytes = 0;
    string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
    string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;

    Response.Clear();
    Response.Buffer = false;
    Response.AddHeader("Accept-Ranges", "bytes");
    Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
    Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
    Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
    Response.AddHeader("Connection", "Keep-Alive");
    Response.ContentEncoding = Encoding.UTF8;

    //Send data
    _BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);

    //Dividing the data in 1024 bytes package
    int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);

    //Download in block of 1024 bytes
    int i;
    for (i = 0; i < maxCount && Response.IsClientConnected; i++)
    {
        Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
        Response.Flush();
    }
    //if blocks transfered not equals total number of blocks
    if (i < maxCount)
        return false;
    return true;
    }
    catch
    {
    return false;
    }
    finally
    {
    Response.End();
    _BinaryReader.Close();
    myFile.Close();
    }
}
else System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
    "FileNotFoundWarning","alert('File is not available now!')", true);
}
else
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(), 
    "NotEligibleWarning", "alert('Sorry! File is not available for you')", true);
}
return false;
}

答案 2 :(得分:0)

一些黑客攻击涉及知道何时发送了最后一块缓冲区或检查HttpResponse.IsClientConnected属性。

答案 3 :(得分:0)

我在Javascript中以不同的方式处理问题,这可能适用于您,也可能不适合您。

  • 使用。创建隐藏的DIV元素 消息'文件正在下载...' 而不是一个弹出框。
  • 下载时显示div 开始
  • 一旦有任何其他元素 单击表单,隐藏div 再次..
  • 您还可以设置计时器以隐藏 之后的下载消息div 时间...

我想一旦用户点击了另一个元素,她或者已经知道下载已经完成,或者她已经准备好做其他事情了,所以消息变得无关紧要并且可以消失......

答案 4 :(得分:0)

执行此操作的方法是在弹出窗口中通过AJAX轮询调用服务器以获取某些响应,该响应将指示文件已刷新。

例如:在发送文件之前,将sessionID + FileName存储在数据库或会话中或者你有什么。

在客户端上,在弹出窗口中,通过AJAX轮询网络服务 - 这甚至可能是像Bool IsContentFlushed(string sessionID, string fileName);

这样的WebMethod

执行Response.Flush();从商店中删除此会话ID + FileName后。

拨打Response.Close()代替Response.End() - 后者非常野蛮,通常会过度杀人。

答案 5 :(得分:0)

尽管这是一个古老的问题,但一直没有得到回答,我相信它应该(更好)回答:

https://stackoverflow.com/a/59010319/313935