我尝试使用进度条对文件复制程序进行编码,但它在百分比计算时崩溃。这是我的代码:
private void operation()
{
byte[] buffer = new byte[1024 * 1024];
using (streamSFD)
{
using (Stream streamOFD = new FileStream(textBox1.Text, FileMode.Open))
{
while (streamOFD.Read(buffer, 0, buffer.Length) > 0)
{
streamSFD.Write(buffer, 0, buffer.Length);
progressBar1.Value = percentage((int)streamOFD.Length, (int)streamSFD.Length);
label2.Text = streamSFD.Length.ToString() + "/" + streamOFD.Length.ToString();
label1.Text = progressBar1.Value.ToString() + "%";
}
}
}
}
private int percentage(int x, int y)
{
return (y * 100) / x;
}
答案 0 :(得分:2)
从评论到问题很明显,百分比方法返回负值。怎么会发生这种情况?
请注意,属性Stream.Length是长,Stream.Position也是如此(也可能是您要用于计算进度百分比的属性)。< / p>
将 long (宽度为64位)转换为 int (宽度为32位)将截取 long 考虑低32位。
想象一下,你有以下积极的长值:
0x1FFFFFF00 (hex) = 8589934336 (decimal)
将其转换为 int 将丢弃高32位,导致:
0xFFFFFF00 (hex) = -256 (decimal)
(在大多数CPU / ALU架构中,负整数通常由其绝对值的two's complement表示。)
解决问题的关键是不截断长值。由于结果百分比值应为0 ... 100范围内的 int 值(它是进度条的百分比),因此Math.Min将用于限制任何计算结果大于100(尽管,对于问题中给出的鳕鱼,计算结果不应超过100)。
private int percentage(long x, long y)
{
return (int) Math.Min( (y * 100) / x, 100L );
}
现在,不再需要将 Stream.Length 转换为 int :
progressBar1.Value = percentage(streamOFD.Length, streamSFD.Length);