0

我有以下代码可以成功复制文件。但是,它有两个问题:

  1. 紧跟在 progressBar.setValue() 之后的 System.out.println() 不会打印 0 到 100 之间的间隔(只打印“0”直到打印“100”的末尾)
  2. 除了由于问题 #1 导致进度条的值可能以某种方式出错的事实之外,在实际代码中,我也在进行其他视觉更改,但直到处理整个文件时它们才会显示。我认为 FileInputStream/FileOutputStream 函数是非阻塞的。如何更改以下代码,以便在操作期间实际上更新进度条?

startJob 方法:

private void startJob(File inFile, File outFile) {
        long offset = 0;
        int numRead = 0;
        byte[] bytes = new byte[8192];
        long fileLength = inFile.length();
        Boolean keepGoing = true;

        progressBar.setValue(0);

        try {
            inputStream = new FileInputStream(inFile);
            outputStream = new FileOutputStream(outFile, false);
            System.out.println("Total file size to read (in bytes) : " + inputStream.available());
        } catch (FileNotFoundException err) {
            inputStream = null;
            outputStream = null;
            err.printStackTrace();
        } catch (IOException err) {
            inputStream = null;
            outputStream = null;
            err.printStackTrace();
        }

        if (inputStream != null && outputStream != null) {
            while (keepGoing) {
                try {
                    numRead = inputStream.read(bytes);
                    outputStream.write(bytes, 0, numRead);
                } catch (IOException err) {
                    keepGoing = false;
                    err.printStackTrace();
                }
                if (numRead > 0) {
                    offset += numRead;
                }

                if (offset >= fileLength) {
                    keepGoing = false;
                }

                progressBar.setValue(Math.round(offset / fileLength) * 100);
                System.out.println(Integer.toString(Math.round(offset / fileLength) * 100));
            }
        }
        if (offset < fileLength) {
            //error
        } else {
            //success
        }

        try {
            inputStream.close();
            outputStream.close();
        } catch (IOException err) {
            err.printStackTrace();
        }
    }
4

2 回答 2

1

我怀疑你是从EDT调用你的冗长方法。例如,将您的操作从 EDT 中删除Runnable,然后调用

SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        progressBar.setValue(value);
        // or any other GUI changes you want to make
    }       
});

否则,您的操作会阻止 EDT,直到它完成,并且在 EDT 被阻止的情况下,将无法处理重绘等事件 -> 直到结束之前没有可见的 GUI 更改。

于 2013-05-05T17:48:18.237 回答
1

表达式的值Math.round(offset / fileLength)将始终等于0(零),因为offset < fileLength.

升级版:

如果要正确执行此计算,则必须将其更改为:

Math.round(((double)offset / (double)fileLength) * 100)
于 2013-05-05T17:48:36.020 回答