我必须触发用户将大文件下载到webbrowser,我在其中创建要在服务器上传输的文件,然后立即将其删除。我已经找到足够的例子来看我应该使用Response.TransmitFile或Response.WriteFile ......但是听说两者都有问题:
WriteFile是同步的,但它会在将文件发送给用户之前将文件缓冲在内存中。由于我正在处理非常大的文件,这可能会导致问题。
TransmitFile不在本地缓冲,因此它适用于大文件,但它是异步的,所以在调用TransmitFile后我无法删除该文件。显然正在刷新文件并不保证我可以删除它吗?
处理此问题的最佳方法是什么?
还有BinaryWrite ......我可以遍历文件流,将其复制到段中吗?
答案 0 :(得分:4)
这是一个很好的解决方案,它使用TransmitFile但允许你在使用委托完成后做一些事情:
http://improve.dk/blog/2008/03/29/response-transmitfile-close-will-kill-your-application
只需用文件删除替换最后的日志记录。
答案 1 :(得分:2)
WriteFile是同步的,但它 之前将文件缓冲在内存中 将其发送给用户。因为我 处理非常大的文件,这个 可能会导致问题。
我相信您可以通过设置禁用WriteFile的缓冲 Response.BufferOutput = false;
一旦将此设置为false,您应该能够在不缓冲的情况下调用WriteFile ...
答案 2 :(得分:0)
你可以将文件提交到磁盘(随机名称等),然后开始发送,但是在你定义的一段时间之后,用一个临时文件名向DB表添加一个条目,让一些清理工作通过这些数据库条目,如果文件已老化,则从磁盘中删除该文件。
答案 3 :(得分:0)
WriteFile 方法用于从服务器下载小文件,size参数必须介于0和最大Int32值之间,在传输文件之前,它将文件缓冲在内存中。 TransmitFile 方法用于从服务器下载大文件,它不会将文件缓冲到内存中。但是在下载文件时尝试删除文件时会抛出异常。下面是下载后删除文件的代码。
FileStream fs = new FileStream(@"D:\FileDownLoad\DeskTop.zip", FileMode.OpenOrCreate);
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
context.Response.AppendHeader("content-disposition", "attachment; filename=" + "DeskTop.zip");
context.Response.ContentType = "application/octet-stream";
context.Response.BinaryWrite(ms.ToArray());
fs.Close();
File.Delete(@"D:\FileDownLoad\DeskTop.zip");