首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FileInputStream / FileOutputStream阻塞?

FileInputStream / FileOutputStream阻塞?
EN

Stack Overflow用户
提问于 2013-05-05 17:41:17
回答 2查看 1.1K关注 0票数 0

我有以下代码,它成功地复制了一个文件。然而,它有两个问题:

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

startJob方法:

代码语言:javascript
复制
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();
        }
    }
EN

回答 2

Stack Overflow用户

发布于 2013-05-05 17:48:18

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

代码语言:javascript
复制
SwingUtilities.invokeLater(new Runnable() {

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

否则,您的操作将阻塞EDT,直到它完成为止,并且由于EDT阻塞,任何事件(如重新绘制等)都不会被处理,->直到结束时都不会看到任何图形用户界面的更改。

票数 1
EN

Stack Overflow用户

发布于 2013-05-05 17:48:36

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

UPD:

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

代码语言:javascript
复制
Math.round(((double)offset / (double)fileLength) * 100)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16387244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档