繁体   English   中英

Java程序因打印行而变慢

[英]Java program slow down by printing line

嗨,我有一个脚本,可以从Web上下载文件,同时可以打印进度。 问题是,打印进度的行会大大减慢程序的速度,是否有任何方法可以阻止这种情况?

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;


public class download {
public static void main(String[] args) {
    try{
        URL u = new URL("http://upload.wikimedia.org/wikipedia/commons/1/16/Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG");
        FileOutputStream fos = new FileOutputStream("C://Users/xxx/Desktop/test.jpg");
        InputStream is = u.openStream();

        long size = u.openConnection().getContentLengthLong();
        int data;
        long done = 0;
        while((data = is.read())!=-1){
            double progress = (double) (done)/(double)(size)*100;
            System.out.println(progress); // if we dont do this then then it completes fast
            fos.write(data);
            done++;
        }
        fos.close();
    }catch(Exception e){
       e.printStackTrace();
    }
}
}

尝试仅打印每个xth循环。

if(done % 10 == 0) System.out.println(progress);

首先,每个I / O操作都需要很高的成本。 现在,您正在为读取的每个字节打印一条消息 (在InputStream#read中注明)。

如果您希望/需要打印进度,请读取一堆KB,通常每4 KB读取一次。 您可以通过使用byte[] buffer从流中读取和写入数据来做到这一点。

BufferedInputStream input = null;
BufferedOutStream output = null;
final int DEFAULT_BUFFER_SIZE = 4 * 1024;
try {
    input = new BufferedInputStream(is, DEFAULT_BUFFER_SIZE);
    output = new BufferedOutputStream(fos, DEFAULT_BUFFER_SIZE);

    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    int length;
    while ((length = input.read(buffer)) > 0) {
        output.write(buffer, 0, length);
        done += length;
        double progress = (double) (done)/(double)(size)*100
        System.out.println(progress);
    }
} catch (IOException e) {
    //log your exceptions...
} finally {
    closeResource(output);
    closeResource(input);
}

并具有以下closeResource方法:

public void closeResource(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (IOException e) {
            logger.error("Error while closing the resource.", e);
        }
    }
}

假设只有(done % 100 == 0)才可以打印行。

另外,您可以使用缓冲的读取方式,这可以加快程序的速度。

建议:不要在循环的每次迭代中都显示进度。 使用一个计数器,确定一个合理的频率,一个数字来修改计数器,并以该选定的频率打印进度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM