如何将文件拆分成部分并下载

时间:2015-04-22 16:03:18

标签: c# http web download

我正在为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);
        }
    }

1 个答案:

答案 0 :(得分:2)

您需要以正确的顺序重新组合文件 - 当前代码会创建随机文件名,即使项目被添加到文件列表中,由于段下载完成时的不可预测时间,它们也会以随机顺序添加。

可能的修复:使用块起始偏移量作为文件名String name = String.Format("file{0:D6}.tmp", Start)的一部分,并在将它们组合之前按名称对文件进行排序。

请注意,{0:D6} formatting用于将索引填充为0,以允许按名称排序更容易,并且避免需要自然排序代码。