文件上传问题

我需要客户端(最终用户)通过浏览器上传大文件(例如类似于Youtube上传大video文件的场景),文件大小不应超过500M字节。

我使用ASP.Net + C#+ VSTS + IIS 7.0作为我的开发平台。 关于如何处理大文件上传问题的任何想法或良好做法? 任何参考样品或文件都表示赞赏。

   

这在IIS7中不起作用! httpRuntime适用于IIS6和下面的版本。 在IIS7中允许大文件上传的正确方法是:

1)将以下行添加到web.config文件:

[Web.config] IIS7的maxAllowedContentLength属性

        

2)然后打开文件C:\ Windows \ System32 \ inetsrv \ config \ applicationHost.config并找到该行:

 

overrideModeDefault应该是Allow。

您需要设置maxRequestLength以正确处理大文件并设置executionTimeout以便IIS不会放弃web.config文件中的请求

    

Jon Gallowy关于上传大文件的文章中有更多详细信息。

以下是关于在asp.net 2.0中上传文件的MSDN文章

这个相关问题的答案建议使用SWFUpload或NeatUpload通过浏览器上传大文件。 NeatUpload是一个ASP.NET组件,可能非常适合您的环境。

还有JUpload 。

几乎所有处理超大型上传的网站都默认使用Adobe Flash。 通常它们会回归到简单的浏览器上传,但是在闪存中管理当前上载的进度要容易得多。

我遇到了这个问题,并在此处找到了基于Jonathan代码的解决方案。 他的代码存在一些问题,但这是我的解决方案。 如果你想上传一个像1Gbyte文件这样的大文件,你必须丢弃文件并通过几个请求发送它(一个请求给出超时)。 首先设置客户端和服务器端的最大限制。

        

    

然后将文件分块,并发送每个chuck,等待响应并发送下一个块。 这是javascript和控制器代码。

  




用于查询,调用控制器和更新进度条的Javascript代码:

  var progressBarStart = function() { $("#progressbar_container").show(); } var progressBarUpdate = function (percentage) { $('#progressbar_label').html(percentage + "%"); $("#progressbar").width(percentage + "%"); } var progressBarComplete = function() { $("#progressbar_container").fadeOut(500); } var file; $('#fileInput').change(function(e) { file = e.target.files[0]; }); var uploadCompleted = function() { var formData = new FormData(); formData.append('fileName', file.name); formData.append('completed', true); var xhr2 = new XMLHttpRequest(); xhr2.onload = function() { progressBarUpdate(100); progressBarComplete(); } xhr2.open("POST", "/Upload/UploadComplete?fileName=" + file.name + "&complete=" + 1, true); xhr2.send(formData); } var multiUpload = function(count, counter, blob, completed, start, end, bytesPerChunk) { counter = counter + 1; if (counter <= count) { var chunk = blob.slice(start, end); var xhr = new XMLHttpRequest(); xhr.onload = function() { start = end; end = start + bytesPerChunk; if (count == counter) { uploadCompleted(); } else { var percentage = (counter / count) * 100; progressBarUpdate(percentage); multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); } } xhr.open("POST", "/Upload/MultiUpload?id=" + counter.toString() + "&fileName=" + file.name, true); xhr.send(chunk); } } $("#VideoDiv").on("click", "#btnUpload", function() { var blob = file; var bytesPerChunk = 3757000; var size = blob.size; var start = 0; var end = bytesPerChunk; var completed = 0; var count = size % bytesPerChunk == 0 ? size / bytesPerChunk : Math.floor(size / bytesPerChunk) + 1; var counter = 0; progressBarStart(); multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); }); 

这里是上传控制器,用于存储chucnk(“App_Data / Videos / Temp”),然后合并它们并存储在(“App_Data / Videos”)中:

 public class UploadController : Controller { private string videoAddress = "~/App_Data/Videos"; [HttpPost] public string MultiUpload(string id, string fileName) { var chunkNumber = id; var chunks = Request.InputStream; string path = Server.MapPath(videoAddress+"/Temp"); string newpath = Path.Combine(path, fileName+chunkNumber); using (FileStream fs = System.IO.File.Create(newpath)) { byte[] bytes = new byte[3757000]; int bytesRead; while ((bytesRead=Request.InputStream.Read(bytes,0,bytes.Length))>0) { fs.Write(bytes,0,bytesRead); } } return "done"; } [HttpPost] public string UploadComplete(string fileName, string complete) { string tempPath = Server.MapPath(videoAddress + "/Temp"); string videoPath = Server.MapPath(videoAddress); string newPath = Path.Combine(tempPath, fileName); if (complete=="1") { string[] filePaths = Directory.GetFiles(tempPath).Where(p=>p.Contains(fileName)).OrderBy(p => Int32.Parse(p.Replace(fileName, "$").Split('$')[1])).ToArray(); foreach (string filePath in filePaths) { MergeFiles(newPath, filePath); } } System.IO.File.Move(Path.Combine(tempPath, fileName),Path.Combine(videoPath,fileName)); return "success"; } private static void MergeFiles(string file1, string file2) { FileStream fs1 = null; FileStream fs2 = null; try { fs1 = System.IO.File.Open(file1, FileMode.Append); fs2 = System.IO.File.Open(file2, FileMode.Open); byte[] fs2Content = new byte[fs2.Length]; fs2.Read(fs2Content, 0, (int) fs2.Length); fs1.Write(fs2Content, 0, (int) fs2.Length); } catch (Exception ex) { Console.WriteLine(ex.Message + " : " + ex.StackTrace); } finally { if (fs1 != null) fs1.Close(); if (fs2 != null) fs2.Close(); System.IO.File.Delete(file2); } } } 

但是,如果两个用户同时上传具有相同名称的文件,则会出现一些问题,您必须处理此问题。 通过读取responseText,您可以捕获一些错误和exception并修剪它。