2015-04-22 41 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

下載每個文件後,臨時名稱將添加到名稱數組中。 mergeclean函數遍歷該數組並加入文件。所以它按照數組中文件的順序進行合併。但是因爲它按照正確的順序下載。我猜它正在按照正確的順序合併。 @RonBeyer – gregyjames

+0

創建文件的校驗和發送前,然後確認下載後 –

回答

2

您需要在正確的碎片重組文件order - 當前代碼創建隨機文件名稱,即使項目被添加到文件列表中,由於unp也會隨機添加段落下載完成後可重新引導的時間。

可能的解決辦法:使用塊起始偏移作爲文件名String name = String.Format("file{0:D6}.tmp", Start)的一部分,並將它們組合回來之前按名稱排序文件。

請注意,{0:D6}formatting用於填充索引爲0,以允許按名稱排序更容易,並避免需要自然排序代碼。

+0

好吧,我把你的指教,我現在排序前陣我合併。但問題仍然存在,它下載的圖像仍然損壞。任何其他想法? – gregyjames

+0

@Chocoloco我假設你已經修復了在評論中指出的代碼... –

+0

什麼關閉一個代碼? – gregyjames