测量Java下载速度

6

我正在处理有关软件下载文件的问题,以下是我的成果:我已经成功地下载了文件并且能够获取下载进度。但仍有一项任务未完成:测量下载速度。希望您能提供帮助。谢谢。

这是当前下载方法的代码:

    public void run()
    {
        OutputStream out = null;
        URLConnection conn = null;
        InputStream in = null;
        try
        {
            URL url1 = new URL(url);
            out = new BufferedOutputStream(
            new FileOutputStream(sysDir+"\\"+where));
            conn = url1.openConnection();
            in = conn.getInputStream();
            byte[] buffer = new byte[1024];
            int numRead;
            long numWritten = 0;
            double progress1;
            while ((numRead = in.read(buffer)) != -1)
            {
                out.write(buffer, 0, numRead);
                numWritten += numRead;
                this.speed= (int) (((double)
                buffer.length)/8);
                progress1 = (double) numWritten;
                this.progress=(int) progress1;
            }
        }
        catch (Exception ex)
        {
            echo("Unknown Error: " + ex);
        }
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
                if (out != null)
                {
                    out.close();
                }
            }
            catch (IOException ex)
            {
                echo("Unknown Error: " + ex);
            }
        }
    }
3个回答

9
同测量任何其他事物一样。 System.nanoTime() 返回一个 Long 值,您可以用它来测量某个操作所需的时间:
Long start = System.nanoTime();
// do your read
Long end = System.nanoTime();

现在你有读取X个字节所需的纳秒数。进行计算,就可以得出下载速率。
很可能你正在寻找每秒字节数。要做到这一点,要跟踪你已经读取的总字节数,并检查是否已经过去了一秒钟。一旦过去一秒钟,根据你在那段时间内读取的字节数来计算速率。重新计算总数,重复执行。

InputStream.read() 的时间转换为 KB-MB-GB/s 的公式是什么?这个答案有助于测量 InputStream.read() 的执行时间。 - user5395084

2

这是我的实现


while (mStatus == DownloadStatus.DOWNLOADING) {
            /*
             * Size buffer according to how much of the file is left to
             * download.
             */
            byte buffer[];
            // handled resume case.
            if ((mSize < mDownloaded ? mSize : mSize - mDownloaded <= 0 ? mSize : mSize - mDownloaded) > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[(int) (mSize - mDownloaded)];
            }

            // Read from server into buffer.
            int read = stream.read(buffer);
            if (read == -1)
                break;// EOF, break while loop

            // Write buffer to file.
            file.write(buffer, 0, read);
            mDownloaded += read;
            double speedInKBps = 0.0D;
            try {
                long timeInSecs = (System.currentTimeMillis() - startTime) / 1000; //converting millis to seconds as 1000m in 1 second
                speedInKBps = (mDownloaded / timeInSecs) / 1024D;
            } catch (ArithmeticException ae) {

            }
            this.mListener.publishProgress(this.getProgress(), this.getTotalSize(), speedInKBps);
        }

1

我可以给你一个大致的想法。在下载开始时启动计时器。现在,将“已下载百分比”乘以“下载大小”,然后除以“经过的时间”。这会给你平均下载时间。希望我能让你走上正确的轨道!

你可以像Brian建议的那样使用System.nanoTime();

在while循环之外放置long startTime = System.nanoTime();,而long estimatedTime = System.nanoTime() - startTime;将为您提供循环内经过的时间。


1
我不知道该如何添加它,我有一个用于获取进度的计时器,但在GUI上。 - Jesus David Gulfo Agudelo
将长时间的 startTime = System.nanoTime(); 放在 while 循环之外。然后,使用 long estimatedTime = System.nanoTime() - startTime; 可以得到当前时间。 - Anirudh Ramanathan
尝试过这样写:在while循环外面加上long startTime = System.nanoTime();,在buffer写入后,在循环内部加上Long end = System.currentTimeMillis()*1000;,但是好像只能运行一次?同时还添加了speed= (int) ((1024/(double) (start-end)));,因为buffer有1024字节。 - Jesus David Gulfo Agudelo
@JesusDavidGulfoAgudelo,嗨,我也在寻找同样的东西。按照你上面的评论所述进行操作后,你的代码是否能够正常工作? - Amogh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接