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