2015-04-22 3 views
0

Я работаю над сплит-загрузчиком для C#. Он загружается отлично (так что логика работает), но проблема в том, что любой файл, который он загружает, развращает. Я понятия не имею, как это исправить. Вот код:Как разбить файл на части и загрузить

private void mergeClean() 
    { 
     const int chunkSize = 1 * 1024; // 2KB 
     using (var output = File.Create("output.jpg")) 
     { 
      foreach (var file in Files) 
      { 
       using (var input = File.OpenRead(file)) 
       { 
        var buffer = new byte[chunkSize]; 
        int bytesRead; 
        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
        { 
         output.Write(buffer, 0, bytesRead); 
        } 
       } 
      } 
     } 

     foreach (var file in Files) 
     { 
      File.Delete(file); 
     } 
    } 

    private void SaveFileStream(String path, Stream stream) 
    { 
     var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write); 
     stream.CopyTo(fileStream); 
     fileStream.Dispose(); 
    } 

    public void SplitDownload(string URL) 
    { 
     System.Net.WebRequest req = System.Net.HttpWebRequest.Create(URL); 
     req.Method = "HEAD"; 
     System.Net.WebResponse resp = req.GetResponse(); 
     var responseLength = double.Parse(resp.Headers.Get("Content-Length")); 
     var partSize = Math.Ceiling(responseLength/10); 
     var previous = 0; 

     for (int i = (int)partSize; i <= responseLength; i = i + (int)partSize) 
     { 
      Thread t = new Thread(() => Download(URL, previous, i)); 
      t.Start(); 
      t.Join(); 
      previous = i; 
     } 

     mergeClean(); 
    } 

    private void Download(string URL, int Start, int End) 
    { 
     Console.WriteLine(String.Format("{0},{1}", Start, End)); 

     HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL); 
     myHttpWebRequest.AddRange(Start, End); 
     HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 
     Stream streamResponse = myHttpWebResponse.GetResponseStream(); 
     String name = GenerateTempName(); 
     SaveFileStream(name, streamResponse); 
     Files.Add(name); 
    } 

Вот пример того, что он делает:

Original Downloaded

ОБНОВЛЕНО КОД:

static string GenerateTempName(int start) 
    { 
     String name = String.Format("{0:D6}.tmp", start); 
     return name; 
    } 

    static public List<string> Files = new List<string>(); 

    static private void mergeClean() 
    { 
     Files.Sort(); 
     const int chunkSize = 1 * 1024; // 2KB 
     using (var output = File.Create("output.jpg")) 
     { 
      foreach (var file in Files) 
      { 
       using (var input = File.OpenRead(file)) 
       { 
        var buffer = new byte[chunkSize]; 
        int bytesRead; 
        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
        { 
         output.Write(buffer, 0, bytesRead); 
        } 
       } 
      } 
     } 

     foreach (var file in Files) 
     { 
      File.Delete(file); 
     } 
    } 
+3

Как вы гарантируете, что файлы будут считаны/перестроены в правильном порядке? –

+0

После загрузки каждого файла имя temp добавляется в массив имен. Функция mergeclean выполняет итерацию через этот массив и присоединяет файлы. Таким образом, он объединяется в порядке файлов в массиве. Но так как это загрузка в правильном порядке. Я предполагаю, что это слияние в правильном порядке. @RonBeyer – gregyjames

+0

Создайте контрольную сумму файла перед отправкой, затем подтвердите его после загрузки –

ответ

2

Вы должны рекомбинировать файл из кусочков в правильной order - текущий код создает случайные имена файлов и даже если элементы добавляются в список файлов, которые они добавляются в случайном порядке из-за отсутствия время завершения, когда завершается загрузка сегмента.

Возможное исправление: используйте начальное смещение блока как часть имени файла String name = String.Format("file{0:D6}.tmp", Start) и сортируйте файлы по имени перед объединением их обратно.

Отметьте, что {0:D6}formatting используется для индексации с индексом 0, чтобы упростить сортировку по имени и избежать необходимости в натуральном коде сортировки.

+0

Хорошо, я взял ваш совет, и теперь я сортирую массив, прежде чем слить его. Однако проблема все еще сохраняется, и изображения, которые она загружает, все еще повреждены. любые другие идеи? – gregyjames

+0

@Chocoloco Я предполагаю, что вы исправили один за другим код, указанный в комментариях ... –

+0

Что от одного кода? – gregyjames

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