2009-06-20 5 views
6

Мне нужен клиент (конечный пользователь) через браузер для загрузки больших файлов (например, похожих на сценарий Youtube, который загружает большие видеофайлы), размер файла не должен превышать 500 Мбайт.проблема с загрузкой файла

Я использую ASP.Net + C# + VSTS + IIS 7.0 в качестве платформы разработки. Любые идеи или рекомендации относительно того, как справляться с большой проблемой загрузки файлов? Любые эталонные образцы или документы оценены.

ответ

2

this related questionSWFUpload или NeatUpload для размещения больших файлов через браузер. NeatUpload - компонент ASP.NET, который вполне может соответствовать вашей среде.

Существует также JUpload.

+0

Спасибо, Колин, еще один вопрос, почему использование RIA-решения является предпочтительным, потому что лучше загружать производительность или что-то еще? – George2

+1

Поддержка браузера для стандартного HTTP не позволяет такие вещи, как указание, какие типы файлов разрешены, а также такие, как progressbars, лучше поддерживаются flash/java. –

+0

1. Использование элемента управления FileUpload не может указывать тип файла? Я запутался. 2. Я думаю, что использование решения, не основанного на RIA, могло бы также реализовать индикатор выполнения, например, как мы загружаем вложение в Gmail. Таким образом, это не означает, что использование простого Http не может реализовать индикатор выполнения. Любые комментарии? – George2

2

Вам нужно установить maxRequestLength соответствующим образом обрабатывать большой файл, а также установить ExecutionTimeout так, что IIS не отказывается от запроса, в файле web.config

<system.web> 
    <httpRuntime executionTimeout="300" maxRequestLength="512000" /> 
</system.web> 

Гораздо больше полной информации являются here в Jon Статья Галлоу о загрузке больших файлов.

Вот статья на MSDN о загрузке файлов в asp.net 2.0

+0

Спасибо TheVillageIdiot, еще один вопрос, почему использование RIA-решения является предпочтительным, потому что лучше загружать производительность или что-то еще? – George2

+1

Я думаю, что с помощью RIA вы можете дать лучшую обратную связь для долгосрочной работы для пользователя. – TheVillageIdiot

+0

Спасибо, 1. так что только пользовательский опыт? Нет загруженности или других преимуществ? 2. Почему использование решения, не основанного на RIA, не могло иметь хорошего пользовательского опыта, не могли бы вы привести мне пример? – George2

1

Почти все сайты, которые обрабатывать очень большие файлы загруженные сделать по умолчанию с помощью Adobe Flash. Обычно они возвращаются к простой загрузке браузера, но, управляя вещами, прогресс текущей загрузки значительно облегчается во flash.

+0

Я смущен, вы предлагаете использовать вспышку или нет? – George2

+2

Я думаю, что рекомендация - использовать flash (или java), но разрешить стандартную загрузку HTTP, если у пользователя нет доступной flash/java –

+0

, почему использование решения на основе flash (или java) предпочтительнее, потому что лучше загружать производительность или что-то еще? – George2

6
<system.web> 
     <httpRuntime executionTimeout="300" maxRequestLength="512000" /> 
    </system.web> 

Это не сработает в IIS7! httpRuntime для IIS6 и ниже. Правильный способ позволить большие загрузки файлов в IIS7 является:

1) Добавьте следующие строки в файл web.config:

[Web.config] maxAllowedContentLength атрибут для IIS7

<system.webServer> 
    <security > 
     <requestFiltering> 
      <requestLimits maxAllowedContentLength="1024000000" /> 
     </requestFiltering> 
    </security> 
</system.webServer> 

2) Затем откройте файл C: \ Windows \ System32 \ Inetsrv \ Config \ applicationHost.config и найдите строку:

<section name="requestFiltering" overrideModeDefault="Allow" /> 

overrideModeDefault должны быть Разрешить.

+0

Один вопрос о значении параметра «executeTimeout» в IIS 6. Означает ли это максимальное время всего процесса загрузки? Или это означает максимальное время простоя (в режиме ожидания я подразумеваю, что фрагмент файла не передается из браузера на сервер, поэтому, если продолжать передавать фрагменты файлов, даже если они медленны, не будет времени)? – George2

+0

Другой вопрос: есть ли параметр для указания тайм-аута в IIS 7? – George2

+0

Я почти уверен, что exectutionTimeout относится и к IIS7. В связи с вашим первым вопросом: тайм-аут определяет максимальное количество секунд, которое запрос может выполнять до автоматического отключения ASP.NET. т. е. если ваша загрузка не завершена за 110 секунд (по умолчанию), ASP отключит процесс. –

0

У меня была эта проблема и решение было основано на Jonathan's code here. Есть некоторые проблемы с его кодом, но вот мое решение. Если вы хотите загрузить большой файл, что-то вроде файла 1Gbyte, вам нужно вытащить файл и отправить его по нескольким запросам (один запрос дает тайм-аут). сначала вы устанавливаете максимальный предел для клиентской и серверной сторон.

<system.webServer> 
<security> 
    <requestFiltering> 
    <requestLimits maxAllowedContentLength="2147483647" /> 
    </requestFiltering> 
</security> 
<system.webServer> 

и

<system.web> 
    <httpRuntime targetFramework="4.5" maxRequestLength="2147483647" /> 
</system.web> 

затем кусок файла, и отправить каждый патрон, ждать ответ и отправить следующий блок. вот код javascript и контроллера.

<div id="VideoDiv"> 
     <label>Filename:</label> 
     <input type="file" id="fileInput" /><br/><br/> 
     <input type="button" id="btnUpload" value="Upload a presentation"/><br/><br/> 
     <div id="progressbar_container" style="width: 100%; height: 30px; position: relative; background-color: grey; display: none"> 
      <div id="progressbar" style="width: 0%; height: 100%; position: absolute; background-color: green"></div> 
      <span id="progressbar_label" style="position: absolute; left: 35%; top: 20%">Uploading...</span> 
     </div> 
    </div> 

код Javascript Чак, контроллер вызова и обновление ProgressBar:

 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/Видео/Temp"), а затем объединить их и хранить в («App_Data/Видео»):

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, вы можете поймать некоторую ошибку и исключение и обрезать ее.

Смежные вопросы