Bandysol 2023-07-12 11:18 采纳率: 83.3%
浏览 29
已结题

C#:多线程下载问题

在我对下面这段多线程 下载代码进行测试时,发现下载到的文件都不能正确打开。查看[文件名]-0等文件时,发现文件一开头是正确数据,然而到了一定点后全都是0。请问是什么问题?要怎么解决?源码如下:


public class Download {
    private string URL    {get;set;}  
    private string Path   {get;set;}
    private long   Length {get;set;}
    private int    Threads{get;set;}

    private int  Changeds = 0;
    private bool Stop     = false;

    public Download(string dURL,string dPath = null,int dThreads = 64) {
        URL = dURL;
        Path = dPath;
        Threads = dThreads;
  TestDo();
      }

    private void TestDo() {
        try {
            Path = Path==null ? new Uri(URL).Segments[new Uri(URL).Segments.Length-1] : Path;
            ServicePointManager.DefaultConnectionLimit = Threads + 1;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
            Thread[] downThs = new Thread[Threads+1];
            Thread   pushThs = new Thread(() => {
                try {for (;;) {
                    if (Changeds == Threads+1) {
                        var write =  new FileStream(Path,FileMode.Create,FileAccess.Write);
                        for (int i = 0;i < Threads+1;++i) {
                            var read = new FileStream(Path + "-" + i,FileMode.Open,FileAccess.Read);
                            byte[] buffer = new byte[read.Length];
                            read.Read(buffer,0,buffer.Length);
                            write.Write(buffer,0,buffer.Length);
                            read.Close();
                            #if DEBUG
                            #else
                                File.Delete(Path + "-" + i);
                            #endif
                            Console.WriteLine("文件"+i+"完成合并");
                        }
                        write.Close();
                        break;
                    } else {
                        Thread.Sleep(200);
                    }
                }
                } catch(Exception) {
                    throw;
                    //Changeds = -1;
                }
            });
            Length = WebRequest.Create(URL).GetResponse().ContentLength;
            Console.WriteLine("下载开始!文件大小:"+Length);
            for (int i = 0;i<downThs.Length-1;++i) {
                downThs[i] = new Thread( id => {
                    try{long start = ((Length - (Length % Threads)) / Threads) * (int)id;
                    long end   = start + ((Length - (Length % Threads)) / Threads) - 1;
                    Console.WriteLine("下载开始!我的任务是{0}~{1}",start,end);
                    HttpWebRequest thisdown = (HttpWebRequest)WebRequest.Create(URL);
                    thisdown.AddRange(start,end);
                    var readstream = thisdown.GetResponse().GetResponseStream();
                    var writstream = new FileStream(Path + "-" + ((int)id).ToString(),FileMode.Create,FileAccess.Write);
                    byte[] buffer = new byte[end - start];
                    readstream.Read(buffer,0,buffer.Length);
                    writstream.Write(buffer,0,buffer.Length);
                    writstream.Flush();
                    readstream.Close();
                    writstream.Close();
                    Console.WriteLine((int)id + "号线程完成下载任务!");
                    if (Changeds != -1) {
                        ++Changeds;
                    }
                    if (Stop) {
                        File.Delete(Path + "-" + ((int)id).ToString());
                    }}
                    catch(Exception) {
                        Stop = true;
                        File.Delete(Path + "-" + ((int)id).ToString());
                        throw;
                    }
                });
            }
            downThs[downThs.Length-1] = new Thread(id => {
                try{long start = Length - (Length % Threads);
                long end   = Length;
                Console.WriteLine("下载开始!我的任务是{0}~{1}",start,end);
                HttpWebRequest thisdown = (HttpWebRequest)WebRequest.Create(URL);
                thisdown.AddRange(start,end);
                var readstream = thisdown.GetResponse().GetResponseStream();
                var writstream = new FileStream(Path + "-" + ((int)id).ToString(),FileMode.Create,FileAccess.Write);
                byte[] buffer = new byte[end - start];
                readstream.Read(buffer,0,buffer.Length);
                writstream.Write(buffer,0,buffer.Length);
                writstream.Flush();
                readstream.Close();
                writstream.Close();
                Console.WriteLine((int)id + "号线程完成任务!");
                if (Changeds != -1) {
                    ++Changeds;
                }
                if (Stop) {
                    File.Delete(Path + "-" + ((int)id).ToString());
                }}
                catch (Exception) {
                    Changeds = -1;
                    Stop = true;
                    throw;
                }
            });
            pushThs.Start();
            for (int i = 0;i < downThs.Length;++i) {
                downThs[i].Start(i);
            }
            pushThs.Join();
            Console.WriteLine("完成下载!");
        } catch (Exception) {
            throw;
        }
    }
}
  • 写回答

3条回答 默认 最新

  • wanghui0380 2023-07-12 11:50
    关注
    byte[] buffer = new byte[end - start];
    readstream.Read(buffer,0,buffer.Length) 
     writstream.Write(buffer,0,buffer.Length)
    
    

    你这代码我看不下去,园子味太重了。我就来说说这3句。别的地方不谈,就这3句就有可能写的都是0

    假设 byte[10000] 但read成功了1000,那么剩下9000就都是0对么
    所以
    stream.Read 是带返回值的,他告诉你他成功读取了多少个

    var readcount= readstream.Read(buffer,0,buffer.Length)
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 7月20日
  • 已采纳回答 7月12日
  • 创建了问题 7月12日

悬赏问题

  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振
  • ¥20 pip2.40更新pip2.43时报错