繁体   English   中英

FileInputStream / FileOutputStream阻塞?

[英]FileInputStream / FileOutputStream blocking?

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

  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();
        }
    }

我怀疑你是从美国东部时间调用你冗长的方法。 将EDT中的操作放入其自己的Runnable中,然后再调用,从EDT中删除操作

SwingUtilities.invokeLater(new Runnable() {

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

否则,您的操作会阻止EDT直到完成,并且在EDT被阻止的情况下,不会处理像重绘等事件 - >结束时GUI不会更改。

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

UPD:

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

Math.round(((double)offset / (double)fileLength) * 100)

暂无
暂无

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

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