change double pe = ((double)k / (double)lenth) * 100;with double pe = k; pe = pe * 100 / length;
private void DownLoadFile() { try { WebClient client = new WebClient(); if (!Directory.Exists(Application.StartupPath + @"\update")) { Directory.CreateDirectory(Application.StartupPath + @"\update"); } for (int i = 0; i <= this.listView1.Items.Count - 1; i++) { string fileName = this.listView1.Items[i].SubItems[0].Text; string url = @"http://172.16.120.155/update/UpdateFile/" + fileName; string file = Application.StartupPath + "\\update\\" + fileName; this.label2.Text = "正在下载:" + fileName; Stream myStream = client.OpenRead(url); byte[] bBuffer = new byte[102400]; int nRealCount = 0; DateTime dtStart; TimeSpan ts; int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString()); int cur = 0; progressBar1.Value = 0; FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write); do { dtStart = DateTime.Now; nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length); if (nRealCount > 0) { fs.Write(bBuffer, 0, nRealCount); } ts = DateTime.Now - dtStart; cur = cur + nRealCount; // double pe = ((double)cur / (double)lenth) * 100; // int va = Convert.ToInt32(pe); // progressBar1.Value = va; double pe = cur; pe = pe * 100 / lenth; int va = Convert.ToInt32(pe); progressBar1.Value = va; // this.label2.Text = "正在下载:" + fileName+" "+cur/1024+" KB/"+lenth/1024+" KB"; this.label2.Text = "正在下载:" + fileName + " " + cur / 1024 + " KB/" + lenth / 1024 + " KB"+" 下载速度:"+nRealCount /ts.Milliseconds +"kb/s"; // 计算流量可以用 nRealCount / ts.Seconds来进行估算 } while (nRealCount > 0); fs.Close(); // client.DownloadFile(url, file); this.listView1.Items[i].SubItems.Add("已下载"); } this.progressBar1.Visible = false; this.label2.Text = "正在更新文件,请稍后..."; string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\update"); foreach (string str in fileDir) { int pos = str.LastIndexOf(@"\"); string FileName = str.Substring(pos); string FilePath = Application.StartupPath + FileName; File.Copy(str, FilePath, true); } this.label2.Text = "程序更新已完成!"; this.label1.Text = this.finish; this.btnNext.Enabled = false; this.listView1.Visible = false; this.btnExit.Text = "完成(&F)"; step++; } catch (Exception errMsg) { MessageBox.Show(errMsg.Message); } }
每次运行程序,哪个Catch出来的错误每次都说哪个时候间隔为0
private void DownLoadFile() { try { WebClient client = new WebClient(); if (!Directory.Exists(Application.StartupPath + @"\update")) { Directory.CreateDirectory(Application.StartupPath + @"\update"); } for (int i = 0; i <= this.listView1.Items.Count - 1; i++) { string fileName = this.listView1.Items[i].SubItems[0].Text; string url = @"http://172.16.120.155/update/UpdateFile/" + fileName; string file = Application.StartupPath + "\\update\\" + fileName; this.label2.Text = "正在下载:" + fileName; Stream myStream = client.OpenRead(url); byte[] bBuffer = new byte[10240]; int nRealCount = 0; DateTime dtStart=DateTime.Now ; TimeSpan ts; int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());//得到文件大小 单位为字节 int cur = 0; progressBar1.Value = 0; FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
int value=0;//得到下载量 int counter = 1;//计算是否读取次数 do { if (counter % 10 == 0)//如果读了10次,就算下载速度 { ts = DateTime.Now - dtStart; int perSecondsValue = (int)((double)value / (ts.TotalMilliseconds / 1000)) / 1024; //算出每秒的下载量 this.label3.Text = "速度:" +perSecondsValue +" k/s"; dtStart = DateTime.Now; value = 0; }
nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length); if (nRealCount > 0) { fs.Write(bBuffer, 0, nRealCount); } cur = cur + nRealCount; double pe = cur; pe = pe * 100 / lenth; int va = Convert.ToInt32(pe); progressBar1.Value = va;
属性
WorkerReportsProgress = true
事件
ProgressChanged += new ProgressChangedEventHandler(Form1.OnProgressChanged);
DoWork += new DoWorkEventHandler(worker_DoWork);
实现:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
你的更新代码.....
}增加一个显示进度的窗体Form1,摆个进度条progressBar1
窗体写上此公共方法
public void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
首先发送请求,获取文件的总长度
然后以包为单位向客户端回传数据,每次的量是一样的,即包的大小相同通过这个就能计算出精确进度了
Stream myStream = myWebClient.OpenRead(uriString);
byte[] bBuffer = new byte[1024];
int nRealCount = 0;
DateTime dtStart;
TimeSpan ts;
do
{
dtStart = DateTime.Now;
nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
ts = DateTime.Now - dtStart;
// 计算流量可以用 nRealCount / ts.Seconds来进行估算
}
while( nRealCount > 0 );
不好意思,我真的有点笨,没有理解到你的意思:(
比如说,我要下载Http://172.16.120.15/DownLoad/abc.rar这个文件,它的大小为12.5M
用WebClient下载这个文件,并用进度条显示文件的进度和当前下载了多少.
这个怎么写.我弄了半天都没有弄成功.谢谢了.
1、文件大小:webclient.Headers or webclient.ResponseHeaders来获得;
2、下载固定长度所耗时间,这我前面已经说明了。
3、至于已经下载多少数据,可以在“2”的基础上进行累加即可。这样一个进度条所需要的数据都有了。
我用DownLoadFile()方法,就是得不到当前的下载量.
还有就是
do
{
这个是得到当前的时间
dtStart = DateTime.Now;
这个的值一直是1024,因为前面定义的是这么多.
nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
这个是得到用时多少?
ts = DateTime.Now - dtStart;
// 计算流量可以用 nRealCount / ts.Seconds来进行估算
}
while( nRealCount > 0 );
关键是这个循环有什么用?
关键是这个循环有什么用?由于一个文件是分段下载,所以需要循环进行分批获取。
我的意思是,比如说这外文件,12M,现在下载了2M了,我如何知道当前下载了2M?
我如何知道当前下载了2M???
忘记贴地址了http://community.csdn.net/Expert/TopicView.asp?id=4791058
http://www.codeproject.com/csharp/PIEBALDProgressDialog.asp
{
//try
//{
WebClient client = new WebClient();
if (!Directory.Exists(Application.StartupPath + @"\temp"))
{
Directory.CreateDirectory(Application.StartupPath + @"\temp");
}
for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
{
string fileName = this.listView1.Items[i].SubItems[0].Text;
string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
string file = Application.StartupPath + "\\temp\\" + fileName;
this.label2.Text = "正在下载:" + fileName; Stream myStream = client.OpenRead(url);
byte[] bBuffer = new byte[10240000];
int nRealCount = 0;
DateTime dtStart;
TimeSpan ts;
int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());
int k = 0;
progressBar1.Value = 0;
do
{
dtStart = DateTime.Now;
nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
ts = DateTime.Now - dtStart;
k = k + nRealCount;
double pe = ((double)k / (double)lenth) * 100;
int va = Convert.ToInt32(pe);
progressBar1.Value = va;
// 计算流量可以用 nRealCount / ts.Seconds来进行估算
}
while (nRealCount > 0);
FileStream fstr = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
fstr.Write(bBuffer, 0, k);
fstr.Close(); // client.DownloadFile(url, file);
this.listView1.Items[i].SubItems.Add("已下载");
}
this.progressBar1.Visible = false;
this.label2.Text = "正在更新文件,请稍后...";
string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\temp"); foreach (string str in fileDir)
{
int pos = str.LastIndexOf(@"\");
string FileName = str.Substring(pos);
string FilePath = Application.StartupPath + FileName;
File.Copy(str, FilePath, true);
} this.label2.Text = "程序更新已完成!"; this.label1.Text = this.finish;
this.btnNext.Enabled = false;
this.listView1.Visible = false;
this.btnExit.Text = "完成(&F)";
//}
//catch (Exception errMsg)
//{
// MessageBox.Show(errMsg.Message);
//}
}
现在进度条是显示出来了,但是问题又出来了,在保存文件的时候就出错了,也就是在这里:
如果把Buffer设置小了,就会出现问题:
FileStream fstr = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
fstr.Write(bBuffer, 0, k);
它提示:
"偏移量和长度超出数组的界限,或者计数大于从索引到源集合结尾处的元素数量。"还有就是即使有些小文件下载下来了,也打不开,我想问题可能就是出在上面两句.不知道怎么改.
郁闷.
do
{
dtStart = DateTime.Now;
nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);//Read data here
if( nRealCount > 0 )
fstr.Write(bBuffer, 0, nRealCount);//Write data here
ts = DateTime.Now - dtStart;
k = k + nRealCount;
double pe = ((double)k / (double)lenth) * 100;
int va = Convert.ToInt32(pe);
progressBar1.Value = va;
// 计算流量可以用 nRealCount / ts.Seconds来进行估算
}
while (nRealCount > 0);
这个程序,我还有点疑问: nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
1.就是myStream.Read()这个方法,比如说一个文件大小为15000字节,现在我定义一个Buffer为1024,当我们在do循环里用Read()这个方法时,第一次,读了1024字节,再把它写入一个文件,
当第二次循环时,这个方法怎么知道,从1025开始去文件里读呢? 是不是这个方法会自动判断?还有就是当我把Buffer的值设置得越大,进度条显示的速度越快,这和下载速度没什么关系吧?(我想,可能是我在本机上测试的原因)?最后个问题就是,我基本上每次得到下载的时间都为0(在DO循环里)?
如果是这样就算不出来下载速度了?因为时间就是为0
如果是这样就算不出来下载速度了?因为时间就是为0因为每次下载的数据量太小,即1k,你可以增大buffer,或者用TimeSpan.Milliseconds 来代替TimeSpan.Seconds
:)
Thanks
几百KB文件根本测试不出来,进度条一下就走完了.
下载这个57M的文件,可能花了5秒吧.但测试出来都是0.
最后,我还在IIS里把流量限制为1K/少,
结果下载小文件,能看到进度条的显示了,可能要几十秒,但它的值就为0.(在其它机器上运行的程序)
double pe = ((double)k / (double)lenth) * 100;with
double pe = k;
pe = pe * 100 / length;
{
try
{
WebClient client = new WebClient(); if (!Directory.Exists(Application.StartupPath + @"\update"))
{
Directory.CreateDirectory(Application.StartupPath + @"\update");
}
for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
{
string fileName = this.listView1.Items[i].SubItems[0].Text;
string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
string file = Application.StartupPath + "\\update\\" + fileName;
this.label2.Text = "正在下载:" + fileName; Stream myStream = client.OpenRead(url);
byte[] bBuffer = new byte[102400];
int nRealCount = 0;
DateTime dtStart;
TimeSpan ts;
int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());
int cur = 0;
progressBar1.Value = 0;
FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
do
{
dtStart = DateTime.Now;
nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
if (nRealCount > 0)
{
fs.Write(bBuffer, 0, nRealCount);
}
ts = DateTime.Now - dtStart;
cur = cur + nRealCount;
// double pe = ((double)cur / (double)lenth) * 100;
// int va = Convert.ToInt32(pe);
// progressBar1.Value = va;
double pe = cur;
pe = pe * 100 / lenth;
int va = Convert.ToInt32(pe);
progressBar1.Value = va;
// this.label2.Text = "正在下载:" + fileName+" "+cur/1024+" KB/"+lenth/1024+" KB";
this.label2.Text = "正在下载:" + fileName + " " + cur / 1024 + " KB/" + lenth / 1024 + " KB"+" 下载速度:"+nRealCount /ts.Milliseconds +"kb/s";
// 计算流量可以用 nRealCount / ts.Seconds来进行估算
}
while (nRealCount > 0);
fs.Close();
// client.DownloadFile(url, file);
this.listView1.Items[i].SubItems.Add("已下载");
} this.progressBar1.Visible = false;
this.label2.Text = "正在更新文件,请稍后...";
string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\update"); foreach (string str in fileDir)
{
int pos = str.LastIndexOf(@"\");
string FileName = str.Substring(pos);
string FilePath = Application.StartupPath + FileName;
File.Copy(str, FilePath, true);
} this.label2.Text = "程序更新已完成!"; this.label1.Text = this.finish;
this.btnNext.Enabled = false;
this.listView1.Visible = false;
this.btnExit.Text = "完成(&F)";
step++;
}
catch (Exception errMsg)
{
MessageBox.Show(errMsg.Message);
}
}
{
try
{
WebClient client = new WebClient(); if (!Directory.Exists(Application.StartupPath + @"\update"))
{
Directory.CreateDirectory(Application.StartupPath + @"\update");
}
for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
{
string fileName = this.listView1.Items[i].SubItems[0].Text;
string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
string file = Application.StartupPath + "\\update\\" + fileName;
this.label2.Text = "正在下载:" + fileName; Stream myStream = client.OpenRead(url);
byte[] bBuffer = new byte[10240];
int nRealCount = 0;
DateTime dtStart=DateTime.Now ;
TimeSpan ts;
int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());//得到文件大小 单位为字节
int cur = 0;
progressBar1.Value = 0;
FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
int value=0;//得到下载量
int counter = 1;//计算是否读取次数
do
{
if (counter % 10 == 0)//如果读了10次,就算下载速度
{
ts = DateTime.Now - dtStart; int perSecondsValue = (int)((double)value / (ts.TotalMilliseconds / 1000)) / 1024;
//算出每秒的下载量
this.label3.Text = "速度:" +perSecondsValue +" k/s";
dtStart = DateTime.Now;
value = 0;
}
nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
if (nRealCount > 0)
{
fs.Write(bBuffer, 0, nRealCount);
}
cur = cur + nRealCount;
double pe = cur;
pe = pe * 100 / lenth;
int va = Convert.ToInt32(pe);
progressBar1.Value = va;
this.label2.Text = "正在下载:" + fileName + " " + cur / 1024 + " KB/" + lenth / 1024 + " KB";
value += nRealCount;
counter++;
}
while (nRealCount > 0);
fs.Close();
// client.DownloadFile(url, file);
this.listView1.Items[i].SubItems.Add("已下载");
} this.progressBar1.Visible = false;
this.label3.Visible = false;
this.label2.Text = "正在更新文件,请稍后...";
string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\update"); foreach (string str in fileDir)
{
int pos = str.LastIndexOf(@"\");
string FileName = str.Substring(pos);
string FilePath = Application.StartupPath + FileName;
File.Copy(str, FilePath, true);
} this.label2.Text = "程序更新已完成!"; this.label1.Text = this.finish;
this.btnNext.Enabled = false;
this.listView1.Visible = false;
this.btnExit.Text = "完成(&F)";
step++;
}
catch (Exception errMsg)
{
MessageBox.Show(errMsg.Message);
}
}
这个程序我今天又把下载的代码改了一下,
当在DO循环里读取文件有十次时,用十次的下载量除以十次所用时间,就可算出大概的下载速度.但让我不解的是,如查在循环里读一次文件,就算一下速度, 但是有时这个ts.TotalMilliseconds 为0有时又不为0,按理说这个值每次都不应该为0.还有就是,当我把Buffer的值设置得大一些,下载速度也就快一些.