繁体   English   中英

Swingworker具有FileVisitor类和walkFileTree(),可在目录树中的一组“文件”内部进行内部迭代; 在哪里发布()?

[英]Swingworker with FileVisitor class and walkFileTree(), which iterates internally over a “set” of files in a directory tree; where to publish()?

似乎长时间运行的tree walker任务应在如下类中定义:

  public class TreeWalker extends SwingWorker<Void,String> implements FileVisitor<Path>

并开始这样的地方:

TreeWalker walker = (new TreeWalker());
           walker.execute();

在长时间运行的任务不仅是由发起的,而是由一个单一的通话完全进行了 walkFileTree()在方法Files类。 因此,肯定是必须在doInBackGround()进行调用。

  protected Void doInBackground() throws Exception {
    Files.walkFileTree(SearchyGUI.p , this);
    return null;
  }

请注意, walkTreeFile() 内部为遇到的每个文件调用四个方法。 程序员编写的循环是不可行的。 所以这是我的问题。 如何使用publish()将文件信息作为字符串发送到需要覆盖的process方法? 我见过的示例在doInBackground() publish()内部有publish() ,但在循环内部,在这里是不可能的。

我最关心的四种方法之一是visitFile() ,该walkFileTree()需要能够找到,但我怀疑这是将publish()放在哪里的方法:

  public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
    if (...we want this file...) 
        publish(f.toString());
    return CONTINUE;
  }

我可以把所有的4个方法是walkFileTree()调用一个内部类中doInBackground()但是这似乎是一厢情愿。

PS我不能使用get() ; 这就是重点(据我所知)—获取结果的延迟太多(可能要处理数千个文件才能找到十几个文件),而要等到doInBackground()结束。

==========================================

编辑#3,原始发布时间后50分钟

  public static void doIt(){
      try {
        System.out.println("It begins..."); // This does happen.
        TreeWalker walker = new TreeWalker();
        walker.execute(); 
        SearchyGUI.info.setVisible(true); // Form is displayed, stays blank.
      }      
      catch (Exception e) { System.out.println("Uh-oh"); } // This does NOT happen.
    }   

==========================================

(编辑2,发布后40分钟)

这是我的处理方法。 println没有执行。

protected void process(String s) {
    System.out.println("in process()...");
    report(s); // my method to append text area with another line of file info
}

此外,包含doInBackground()的类语句已更改:

public class TreeWalker extends SwingWorker<Void, String> implements Runnable{

Walking类嵌套在doInBackground()

==========================================

(编辑,发布后20分钟)

编译后却什么也没做:

  protected Void doInBackground() throws Exception 
  {
    class Walking implements FileVisitor<Path>
    {  
      @Override
      public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException 
      {
        String modifyDate    = a.lastModifiedTime().toString().substring(0,10);
        String fpathname = f.toString();// + "\\" + f.getFileName().toString());
        if (...we want this one...) 
            publish(f.getFileName());
        return disposition;
      }
... other methods excluded
    } // end inner class    

    System.out.println("walking??");                                 // We get here ...
    Files.walkFileTree(SearchyGUI.p , (FileVisitor<? super Path>) this);
    System.out.println("Finished walking??");                        // ... but not here.
    return null;
  } // end of doInBackground()

=============================

...另一个freakin的编辑...我当前的班级防御...

public class GUI extends JFrame implements ActionListener, MouseListener, KeyListener

public class TreeWalker extends SwingWorker<Void, String> implements Runnable{

protected Void doInBackground() throws Exception {
  class Walking implements FileVisitor<Path>{ // CLASS INSIDE doInBackground

... zzzzzzzzzzzzzzzzzzzzz ...........

因为TreeWalker扩展了SwingWorker并实现FileVisitor ,所以您可以从任何回调方法中调用publish ,例如...

public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
    publish(dir.toString());
    return FileVisitResult.CONTINUE;
}

现在,根据需要,您将需要使用所需的任何方法将Path元素转换为String

更新了工作示例

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;

public class TreeWalkerExample {

    public static void main(String[] args) {
        new TreeWalkerExample();
    }

    public TreeWalkerExample() {
        TreeWalker tw = new TreeWalker();
        tw.execute();
        try {
            tw.get();
        } catch (InterruptedException | ExecutionException ex) {
            ex.printStackTrace();
        }
    }

    public class TreeWalker extends SwingWorker<Void, Path> implements FileVisitor<Path> {

        @Override
        protected void process(List<Path> chunks) {
            for (Path p : chunks) {
                System.out.println(p);
            }
        }

        @Override
        protected Void doInBackground() throws Exception {
            Path p = Paths.get(System.getProperty("user.home"));
            System.out.println(p);
            Files.walkFileTree(p, this);
            return null;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            FileVisitResult fvr = FileVisitResult.CONTINUE;
            if (dir.getFileName().toString().startsWith(".")) {
                fvr = FileVisitResult.SKIP_SUBTREE;
            }
            return fvr;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            publish(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            return FileVisitResult.TERMINATE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
        }
    }

}

铌,这并不与它的GUI,而是等待工人通过等待完成get返回仅仅意味着作为示例

由于@Madprogrammer不使用GUI,而DID使用get()[在doInBackground()执行完成之前将一直等待),因此,我添加了一个GUI,修改了他的publish(),并包括了对done()的调用,就像糖衣一样在蛋糕上。 我自己的树助行器还没有工作,但是Mad向我展示了方法。 这是新的Mad-with-GUI版本的亮点。

public class TreeWalkerExample {

  static GUI gui;

  public static void main(String args[]) 
  {...invokelater...
     public void run() { 
       gui = new GUI(); 
       gui.setVisible(true); }
   }

      public TreeWalkerExample() { 
        (new TreeWalker()).execute();  
      }

      public class TreeWalker extends SwingWorker<Void,Path> implements FileVisitor<Path> {

          protected Void doInBackground() throws Exception {
              Path p = Paths.get("C:\\","Users","\\Dave","\\Documents","\\Java");
              gui.appendOutput(p.toString());
              Files.walkFileTree(p, this);
              return null;
          }

          public FileVisitResult visitFile(Path file, BasicFileAttributes a) throws IOException{
              publish(file);
              return FileVisitResult.CONTINUE;
          }

          protected void process(List<Path> chunks) {
              for (Path p : chunks) 
                gui.appendOutput(p.getFileName().toString());
          }

          protected void done(){
              gui.appendOutput("\nDone");
          }
    }
    ===================================================================================================
    public class GUI extends javax.swing.JFrame {

      JTextArea output;

      private void btnWalkMouseClicked(java.awt.event.MouseEvent evt) {                                     
        new TreeWalkerExample();
      }                                    

      public void appendOutput(String s){
        output.append("\n" + s);
      }

不是我放弃了SwingWorker,而是只是确定自己对线程不了解,因此决定对此做些事情。 在过去两天里,我通过一个简单得多的项目获得了成功,这促使我将相同的策略应用于我的(各种)Treewalker(项目),该策略现在:(1)在将输出追加到文本区域时不使屏幕闪烁,以及(2)结束并立即按下按钮。

它所要做的就是为“后台” FileVisitor任务使用一个单独的线程(而不是SwingWorker),该线程:(a)让GUI保持“负责”状态,因此能够无缝地接受输出并为用户提供一个按钮按下以中止操作;(b)使代码看起来理智,易于遵循。

因此,@ Mad,再次感谢AGAIN的帮助。 (自11月19日以来,我就不再单独从事此工作!我感到非常沮丧,我只是离开了它,成功完成了其他工作,然后又有勇气再试一次)。

PS我发现Ivar Horton的Beginning Java (7)文本非常有价值。 关于线程的最佳见解。

FWIW以下是我的备份程序的概述:

public class Copy extends Thread{

  public static FileVisitResult disposition = FileVisitResult.CONTINUE;
  static Thread           t ;
  static FilesCopied      output ;   
...
  public static TreeWalker      fv;
...

  public void run() {    
...
    fv             = new TreeWalker();  
    try {
      Files.walkFileTree(UserIO.inputPath,fv);
    }
    catch ...
  }

  public /* inner */ class TreeWalker implements FileVisitor<Path> {
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      maybeCopy(file);
      return disposition;
    }
    public FileVisitResult preVisitDirectory(Path d, BasicFileAttributes a) throws IOException {
      maybeMakeDir(d,fromRootDepth);
      return disposition;     
    }
... 
  } // end TreeWalker

...
  public static void main(String[] args) throws IOException {
    EventQueue.invokeLater(new Runnable()  
      public void run() { gui = new UserIO(); gui.setVisible(true); 
    }});  
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        output = new FilesCopied();
      }});
    t = new Copy();
  }
} // end class Copy
======================
public class UserIO extends JFrame {
...
  public void btnBackupMouseClicked(MouseEvent evt) throws IOException { 
...
      Copy.t.start();
  }

  public void btnStopMouseClicked(MouseEvent evt) throws IOException { 
    Copy.disposition = FileVisitResult.TERMINATE;
  }                                      
}

暂无
暂无

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

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