c# - 如何将文件拆分成多个部分并下载

标签 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);
        }
    }

最佳答案

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

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

注意 {0:D6} formatting用于用 0 填充索引,以便更轻松地按名称排序并避免使用自然排序代码。

关于c# - 如何将文件拆分成多个部分并下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29803079/

相关文章:

javascript - 在输入文本javascript中输入数字时如何显示选项

javascript - 如何从node js post ajax请求中读取数据?

c# - .Net Blazor 优于 Angular、React 或其他 javascript 框架

c# - 组件内的 Blazor 双向绑定(bind)文本区域

.net - http.sys 和响应时间记录

http - 如何将这个 Curl HTTP 翻译成 Arduino C++?

css - 我应该如何消除按钮收缩?

c# - 从 Windows 服务调用 WCF 服务时出现证书错误

c# - 从使用 .NET 3.5 框架构建的应用程序中将 100 万行和 500 列数据从 SQL 数据库导出到 excel

python - 与 curl 一起工作,请求失败;如何修复我的请求代码?