none
WebClient OpenRead()问题 RRS feed

  • 问题

  • 以下代码执行的时候经常会出现不能全部下载的问题:
    =============================================================
     WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.GetEncoding("GB2312");
                Stream stream = client.OpenRead("http://www.vchome.net/dotnet/dotnetdocs/dotnet37.htm");
                using (stream)
                {
                    FileStream fs = File.Open("a.html", FileMode.Create);
                    using (fs)
                    {
                        while (true)
                        {
                            byte[] byts = new byte[100];
                            int r = stream.Read(byts, 0, byts.Length);
                            fs.Write(byts, 0, r);
                            if (r < byts.Length)
                                   {
                                           break;
                                    }
                        }
                    }
                }
                Console.WriteLine("ok");
    ================================================================
    当把红色的代码换成:
                             if (r == 0)
                                    {
                                        break;
                                    }
    时,可以全部下载。
    问题:为什么还没有全部下载完,r的值也有可能小于byts.Length的值呢?而且中间会出现好几次r的值小于byts.Length的值的情况,最后才会全部下载完成。
    2011年4月22日 7:34

答案

  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?


    WebClient 的内置 buffer 的默认大小为 4096,

    有可能当你读取完本地 buffer 的时候,网络传输过来的数据并没有填充满,所以造成你只有小于100的数据可用,

    但事实上数据还没读取完,因此可靠的方式是使用 Stream.EOF 来判断是否读取完所有数据.

    非常感谢你的回复。WebClient的默认buffer能修改吗?

    另外貌似在网络下载时不能读取流的总长度,也没有stream.EOF。

    应该只能用r==0来判断吧?

    再次感谢你的回复,谢谢。

    问题应该是缓存或者是网络传输中的字节是不是丢了,所以不是每次都能全部都满。读取的时候如果加Thread.Sleep()的话,效果又不一样。
    steve
    • 已标记为答案 _qiaohe_ 2011年4月23日 11:13
    2011年4月23日 11:13

全部回复

  • 没人来回答一下吗。。。。
    2011年4月22日 7:54
  • 你好

    或者你可以嘗試用以下的CODE DOWNLOAD 這個PAGE

     WebClient wc = new WebClient();

     

                wc.DownloadFile("http://www.vchome.net/dotnet/dotnetdocs/dotnet37.htm", @"d:\abccc.html");

     

                wc.Dispose();

    Please correct me if my concept is wrong


    Chi
    2011年4月22日 8:22
  • 因为你的文件长度不是 100 的整数倍.
    2011年4月22日 8:29
  • 非常感谢你的回复。

    我只是想知道为什么上面的代码不行。如果页面的数据还没有download完,那么每次download的值都应该是100 bytes,直到最后一次。但是事实上,在全部download之前会出现好几次实际下载字节数比声明的byte数组长度小的情况。

    2011年4月22日 8:51
  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?
    2011年4月22日 8:54
  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?

    即使在你的程序代码没有全部download的情况下,实际上服务器已经把全部页面传给你了,你可以用Fiddler印证这一点.
    2011年4月22日 10:07
  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?


    WebClient 的内置 buffer 的默认大小为 4096,

    有可能当你读取完本地 buffer 的时候,网络传输过来的数据并没有填充满,所以造成你只有小于100的数据可用,

    但事实上数据还没读取完,因此可靠的方式是使用 Stream.EOF 来判断是否读取完所有数据.

    2011年4月22日 10:13
  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?


    WebClient 的内置 buffer 的默认大小为 4096,

    有可能当你读取完本地 buffer 的时候,网络传输过来的数据并没有填充满,所以造成你只有小于100的数据可用,

    但事实上数据还没读取完,因此可靠的方式是使用 Stream.EOF 来判断是否读取完所有数据.

    非常感谢你的回复。WebClient的默认buffer能修改吗?

    另外貌似在网络下载时不能读取流的总长度,也没有stream.EOF。

    应该只能用r==0来判断吧?

    再次感谢你的回复,谢谢。

    2011年4月22日 10:50
  • 你好,如果是文件的总长度不是100整数倍的话,那 么也因该是最后一次小于byte数组的长度,可是现在是,在全部下载完之前会出现好几次实际读取的字节数比声明的byte数组长度少的情况,我不知道是为什么。莫非和服务器缓存有关?


    WebClient 的内置 buffer 的默认大小为 4096,

    有可能当你读取完本地 buffer 的时候,网络传输过来的数据并没有填充满,所以造成你只有小于100的数据可用,

    但事实上数据还没读取完,因此可靠的方式是使用 Stream.EOF 来判断是否读取完所有数据.

    非常感谢你的回复。WebClient的默认buffer能修改吗?

    另外貌似在网络下载时不能读取流的总长度,也没有stream.EOF。

    应该只能用r==0来判断吧?

    再次感谢你的回复,谢谢。

    问题应该是缓存或者是网络传输中的字节是不是丢了,所以不是每次都能全部都满。读取的时候如果加Thread.Sleep()的话,效果又不一样。
    steve
    • 已标记为答案 _qiaohe_ 2011年4月23日 11:13
    2011年4月23日 11:13