受这个xckd 卡通的启发,我想知道向用户提供文件复制/移动的估计的最佳机制是什么?
xkcd 上的 alt 标签内容如下:
他们可能会说“连接可能已丢失”,但进行简单的时间平均会更有趣,让您希望如果您等待 1,163 小时,它最终会完成。
忽略有趣的是,这真的是在 Windows 中完成的吗?其他操作系统呢?有没有更好的办法?
受这个xckd 卡通的启发,我想知道向用户提供文件复制/移动的估计的最佳机制是什么?
xkcd 上的 alt 标签内容如下:
他们可能会说“连接可能已丢失”,但进行简单的时间平均会更有趣,让您希望如果您等待 1,163 小时,它最终会完成。
忽略有趣的是,这真的是在 Windows 中完成的吗?其他操作系统呢?有没有更好的办法?
查看我对类似问题(以及其他答案)的回答,了解如何在 Windows 资源管理器中估算剩余时间。
在我看来,只有一种方法可以得到好的估计:
请注意,如果您要复制许多文件,第一点可能需要相当多的工作。这可能就是为什么微软的人决定不使用它的原因。您需要自行决定该计算产生的额外开销是否值得为您的用户提供更好的估计。
考虑到项目的出列速度比入列速度快,我已经做了类似估计队列何时为空的事情。我对(时间,队列大小)的最近 N 个读数使用线性回归。
这比天真的结果更好
(bytes_copied_so_far / elapsed_time) * bytes_left_to_copy
elapsedTime
”totalCopied
”totalCopied
得到totalElapsed
每个计时器间隔(在本例中为 1000 毫秒)复制的字节数。我们称这个变量为“ bytesPerSec
”bytesPerSec
理论上复制此文件所需的总秒数。我们称这个变量为remainingTime
elapsedTime
从中减去remainingTime
,您可以稍微准确地计算文件复制时间。我认为对话应该承认它们的局限性。这并不烦人,因为它没有给出有用的时间估计,它很烦人,因为它权威地提供了一个明显是胡说八道的估计。
因此,根据当前汇率或迄今为止的平均汇率、滚动平均值丢弃异常值或其他任何值,根据您的喜好进行估算。取决于操作和延迟它的事件的典型持续时间,因此当您知道文件副本涉及网络驱动器时,您可能有不同的算法。但是,直到您的估计在一段时间内相当一致,等于 30 秒或估计时间的 10%如果它被大量加速。
例如,当连接短暂停止时以 1 秒为间隔获取对话消息:
remaining: 60 seconds // estimate is 60 seconds
remaining: 59 seconds // estimate is 59 seconds
remaining: delayed [was 59 seconds] // estimate is 12 hours
remaining: delayed [was 59 seconds] // estimate is infinity
remaining: delayed [was 59 seconds] // got data: estimate is 59 seconds
// six seconds later
remaining: 53 seconds // estimate is 53 seconds
最重要的是,我永远不会显示秒数(只有小时和分钟)。我认为当您坐在那里等待一分钟而计时器在 10 到 20 秒之间跳跃时,这真的很令人沮丧。并始终显示真实信息,例如:xxx/yyyy MB 已复制。
我还会包括这样的内容:
if timeLeft > 5h --> Inform user that this might not work properly if timeLeft > 10h --> Inform user that there might be better ways to move the file if timeLeft > 24h --> Abort and check for problems
如果估计时间变化太大,我也会通知用户
如果不是太复杂,应该有一个自动检查功能,每 1-10 分钟检查一次进程是否仍然存在并正常工作(取决于应用程序)。
说到网络文件复制,最好的办法是计算要传输的文件大小、网络响应等。我曾经使用过的一种方法是:
连接速度 = Ping 并计算 15 KB 包的往返时间。
获取我的文件大小,从理论上看,如果我使用我的连接速度将它分成 15 kb 的包需要多少时间。
开始传输后重新计算我的连接速度并调整将花费的时间。
我自己一直在思考这个问题。我有一个复制例程——通过 Windows 资源管理器风格的界面——它允许将选定的文件从 Android 设备传输到 PC。
一开始,我知道要复制的文件的总大小,当我使用 C#.NET 时,我使用秒表来获取经过的时间,并且在复制过程中,就字节而言,我保留了迄今为止复制的全部内容。
我还没有真正测试过它,但最好的方法似乎是 -
估计=经过*((totalSize - 复制的SoFar)/复制的SoFar)
我从来没有按照你们解释的方式看到它——通过 trasfeed 字节和总字节。
如果您改为使用每个文件的字节数和文件数,“体验”总是更有意义(不好/不准确)。这就是估计如何剧烈波动的方式。
如果您首先传输大文件,即使连接是静态的,估计也会很长。就像它天真地认为所有文件都是如此传输的文件的平均大小,然后假设平均文件大小将在整个时间内保持准确,然后进行猜测。
当连接“速度”变化时,这种方式和其他方式都会变得更糟......