在Windows Java中,如何仅从文件夹及其所有内容中取消设置只读?

时间:2014-11-02 05:07:28

标签: java windows file-io

说我有一个文件夹C:\stuff。在stuff中,有数千个杂项文件和其他文件夹。

在Windows中,我只需转到该文件夹​​,右键单击它并单击属性,取消设置只读标志,然后将操作应用于父文件夹,所有子文件夹和所有文件。

但是,我想通过在GUI中单击JButton来自动化Java。 ActionListener内的代码会是什么样的?甚至可以这样做吗?我是否可以利用某些内容,例如将Java写入PowerShellcmd

1 个答案:

答案 0 :(得分:0)

您可以使用Files.walkFileTree执行此操作,但如果您在ActionListener(或从ActionListener调用的任何方法)中执行此操作,则在更改文件时将冻结您的应用程序。这是因为在事件调度线程上调用了ActionListener,该线程与完成键盘输入,鼠标输入和屏幕绘制的线程相同。因此,当您在该线程中执行耗时的操作时,您的应用程序将忽略键盘输入和鼠标输入,如果它被任何其他应用程序视觉遮挡,然后移动或关闭,它将不会重绘。

如果您不关心应用程序是否挂起,您可以在ActionListener中执行操作:

Files.walkFileTree(rootDirectory, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir,
                                             BasicFileAttributes attr)
    throws IOException {
        Files.setAttribute(dir, "dos:readonly", false);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file,
                                     BasicFileAttributes attr)
    throws IOException {
        Files.setAttribute(file, "dos:readonly", false);
        return FileVisitResult.CONTINUE;
    }
});

但实际上,您不应该挂起事件派发线程。文件I / O应该在另一个线程中完成。有很多方法可以做到这一点,但SwingWorker似乎对许多人来说最简单:

static void updateReadOnlyInTree(final Path root,
                                 Window parentWindow) {

    SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
        @Override
        public Void doInBackground()
        throws IOException {

            Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(
                                                Path dir,
                                                BasicFileAttributes attr)
                throws IOException {
                    Files.setAttribute(dir, "dos:readonly", false);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path file,
                                                 BasicFileAttributes attr)
                throws IOException {
                    Files.setAttribute(file, "dos:readonly", false);
                    return FileVisitResult.CONTINUE;
                }
            });

            return null;
        }
    };

    final JOptionPane waitPane = new JOptionPane("Updating files\u2026",
        JOptionPane.INFORMATION_MESSAGE);
    final JDialog waitDialog = 
        waitPane.createDialog(parentWindow, "Files Update");

    worker.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent event) {
            if (event.getPropertyName().equals("state") &&
                event.getNewValue() == SwingWorker.StateValue.DONE) {

                waitPane.setValue(JOptionPane.CLOSED_OPTION);
            }
        }
    });

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            waitDialog.setVisible(true);
        }
    });

    worker.execute();
}

在更改任何文件之前,您甚至可以更进一步计算文件,然后使用ProgressMonitor而不是JOptionPane。