Java 如何在使用BufferedOutputStream复制文件时获得进度&;摇摆工人

Java 如何在使用BufferedOutputStream复制文件时获得进度&;摇摆工人,java,swingworker,Java,Swingworker,我正在将文件从计算机复制到外部设备,如SD卡,我希望在文件复制过程中获得进度。我正在使用SwingWorker,以便可以同时复制多个文件。我不确定如何获取当前进度并将其发送到SwingWorker publish()方法。以下是我复制文件的代码: FileInputStream finStream = new FileInputStream(sourceFile); FileOutputStream foutStream = new FileOutputStream(destFile); /*

我正在将文件从计算机复制到外部设备,如SD卡,我希望在文件复制过程中获得进度。我正在使用SwingWorker,以便可以同时复制多个文件。我不确定如何获取当前进度并将其发送到SwingWorker publish()方法。以下是我复制文件的代码:

FileInputStream finStream = new FileInputStream(sourceFile);
FileOutputStream foutStream = new FileOutputStream(destFile);

/*
 * Adapted from http://www.java2s.com/Code/Java/File-Input Output/UseBufferedInputStreamandBufferedOutputStreamtocopybytearray.html
 */
BufferedInputStream bufIS = new BufferedInputStream(finStream);     
BufferedOutputStream bufOS = new BufferedOutputStream(foutStream);

byte[] byteBuff = new byte[32 * 1024];
int len;
while ((len = bufIS.read(byteBuff)) > 0){
    bufOS.write(byteBuff, 0, len);
    publish(/*What do I put here?*/);
}

bufIS.close();
bufOS.close();
  • 首先找到文件的大小。 在java.io.File中使用length方法
  • 使用“len”变量确定在循环的当前迭代中复制了多少字节
  • 使用该数据计算百分比并使用该百分比
  • 注意:写入的数据可能会被写入缓冲区,并将根据分配的缓冲区大小进行刷新(但这不应妨碍计算)。

    Swingworker已经有一个“进度功能”,请使用它,而不是
    发布/处理

    long size = file.length();
    
    int count = 0;
    int progress;
    while ((len = bufIS.read(byteBuff)) > 0) {
      ...
      count += len;
      if (size > 0L) {
        progress = (int) ((count * 100) / size);
        setProgress(progress);
      }
    }
    
    然后,您可以在
    EDT
    中使用
    worker.getProgress()
    ,或者将
    PropertyChangeListener
    与progressBar或其他工具一起使用

    例如:


    如果您更喜欢
    publish/process
    ,那么
    公共类MyWorker扩展SwingWorker
    ,您将能够使用整数调用
    publish
    ,我尝试过这样做,但我不清楚我要传递的数据类型,因为它不能是int。它需要是List,在文档中定义FlipAir的地方,提到的“FlipAir”类在该站点中提到了该示例的一部分。请查看帮助您完成此操作的页面。我正在尝试您对PropertyChangeListener的第二个建议,但是evt.getPropertyName()始终返回“state”而不是“progress”。你知道为什么吗?你必须调用
    setProgress(progress),在swing Worker中(函数doInBackground)。也许我的答案不清楚,但你必须在setProgress(progress)之后添加getProgress(),然后触发PropertyChangeListener。这很奇怪,你不需要调用
    getProgress
    ,但如果它起作用,你可以标记我的答案。我拿出getProgress,它起作用了,所以我不需要那个。我不知道为什么一开始它没有检测到进度事件,但现在它检测到了。嗯,这很有效。谢谢
    public class MyWorker extends SwingWorker<Void, Void> implements PropertyChangeListener {
    
        public MyWorker() {
          addPropertyChangeListener(this);
        }
    
        ....
        /* Your code */
        ....
    
       @Override
       public void propertyChange(PropertyChangeEvent evt) {
    
          if ("progress".equals(evt.getPropertyName())) {
            myProgressBar.setValue((Integer) evt.getNewValue());
          }
       }
    
    }
    
    MyWorker worker = new MyWorker();
    worker.addPropertyChangeListener(new PropertyChangeListener() {
    
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if ("progress".equals(evt.getPropertyName())) {
                myProgressBar.setValue((Integer) evt.getNewValue());
            }
        }
    }