2013-05-05 35 views
0

我有以下代码成功地复制了一个文件。但是,有两个问题是:)FileInputStream/FileOutputStream阻止?

  1. 的的System.out.println(在progressBar.setValue()后不打印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(); 
     } 
    } 
+0

[不确定JProgressBar更新已无法正常工作(HTTP的可能重复://计算器。 com/questions/8812718/jprogressbar-update-not-working) – 2013-05-05 17:46:29

+1

您是否使用[ProgressMonitorInputStream](http://docs.oracle.com/javase/7/docs/api/javax/swing/ProgressMonitorInputStream.html )?这可以为你简化很多工作。 – 2013-05-05 17:46:46

+1

FileInputStream如何能够非阻塞并仍然返回已读取的内容? – 2013-05-05 17:47:42

回答

1

我怀疑你在呼唤从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更改。

1

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

UPD:

如果你想这样做正确的计算,你必须将其更改为:

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