如何从目录和子目录中复制具有特定扩展名的所有文件?

时间:2011-10-17 16:49:08

标签: java java-io

我知道如何将文件从一个目录复制到另一个目录,我想要帮助的是复制一个带有.jpg或.doc扩展名的文件。

例如。

D:/Pictures/Holidays

复制所有文件

扫描上述路径中的所有文件夹,并将所有jpg转移到提供的目的地。

5 个答案:

答案 0 :(得分:3)

这样可行,但可以为大文件增强文件'copy(File file,File outputFolder)'方法:

package net.bpfurtado.copyfiles;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class CopyFilesFromType
{
    public static void main(String[] args)
    {
        new CopyFilesFromType().copy("jpg", "C:\\Users\\BrunoFurtado\\Pictures", "c:/temp/photos");
    }

    private FileTypeOrFolderFilter filter = null;

    private void copy(final String fileType, String fromPath, String outputPath)
    {
        filter = new FileTypeOrFolderFilter(fileType);
        File currentFolder = new File(fromPath);
        File outputFolder = new File(outputPath);
        scanFolder(fileType, currentFolder, outputFolder);
    }

    private void scanFolder(final String fileType, File currentFolder, File outputFolder)
    {
        System.out.println("Scanning folder [" + currentFolder + "]...");
        File[] files = currentFolder.listFiles(filter);
        for (File file : files) {
            if (file.isDirectory()) {
                scanFolder(fileType, file, outputFolder);
            } else {
                copy(file, outputFolder);
            }
        }
    }

    private void copy(File file, File outputFolder)
    {
        try {
            System.out.println("\tCopying [" + file + "] to folder [" + outputFolder + "]...");
            InputStream input = new FileInputStream(file);
            OutputStream out = new FileOutputStream(new File(outputFolder + File.separator + file.getName()));
            byte data[] = new byte[input.available()];
            input.read(data);
            out.write(data);
            out.flush();
            out.close();
            input.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private final class FileTypeOrFolderFilter implements FileFilter
    {
        private final String fileType;

        private FileTypeOrFolderFilter(String fileType)
        {
            this.fileType = fileType;
        }

        public boolean accept(File pathname)
        {
            return pathname.getName().endsWith("." + fileType) || pathname.isDirectory();
        }
    }
}

答案 1 :(得分:1)

列出文件时使用FileFilter

在这种情况下,过滤器将选择目录和任何感兴趣的文件类型。


以下是获取目录结构中文件类型列表的快速示例(粗略地从另一个项目中删除)。

import java.io.*;
import java.util.ArrayList;

class ListFiles {

    public static void populateFiles(File file, ArrayList<File> files, FileFilter filter) {
        File[] all = file.listFiles(filter);

        for (File f : all) {
            if (f.isDirectory()) {
                populateFiles(f,files,filter);
            } else {
                files.add(f);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String[] types = {
            "java",
            "class"
        };
        FileFilter filter = new FileTypesFilter(types);
        File f = new File("..");
        ArrayList<File> files = new ArrayList<File>();
        populateFiles(f, files, filter);

        for (File file : files) {
            System.out.println(file);
        }
    }
}

class FileTypesFilter implements FileFilter {

    String[] types;

    FileTypesFilter(String[] types) {
        this.types = types;
    }

    public boolean accept(File f) {
        if (f.isDirectory()) return true;
        for (String type : types) {
            if (f.getName().endsWith(type)) return true;
        }
        return false;
    }
}

答案 2 :(得分:1)

使用以下文件walker树类来执行此操作

static class TreeCopier implements FileVisitor<Path> {

        private final Path source;
        private final Path target;
        private final boolean preserve;
        private String []fileTypes;

        TreeCopier(Path source, Path target, boolean preserve, String []types) {
            this.source = source;
            this.target = target;
            this.preserve = preserve;
            this.fileTypes = types;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
            // before visiting entries in a directory we copy the directory
            // (okay if directory already exists).
            CopyOption[] options = (preserve)
                    ? new CopyOption[]{COPY_ATTRIBUTES} : new CopyOption[0];

            Path newdir = target.resolve(source.relativize(dir));
            try {
                Files.copy(dir, newdir, options);
            } catch (FileAlreadyExistsException x) {
                // ignore
            } catch (IOException x) {
                System.err.format("Unable to create: %s: %s%n", newdir, x);
                return SKIP_SUBTREE;
            }
            return CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            String fileName = file.toFile().getName();
            boolean correctType = false;
            for(String t: fileTypes) {
                if(fileName.endsWith(t)){
                    correctType = true;
                    break;
                }
            }
            if(correctType)
                copyFile(file, target.resolve(source.relativize(file)), preserve);
            return CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
            // fix up modification time of directory when done
            if (exc == null && preserve) {
                Path newdir = target.resolve(source.relativize(dir));
                try {
                    FileTime time = Files.getLastModifiedTime(dir);
                    Files.setLastModifiedTime(newdir, time);
                } catch (IOException x) {
                    System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
                }
            }
            return CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) {
            if (exc instanceof FileSystemLoopException) {
                System.err.println("cycle detected: " + file);
            } else {
                System.err.format("Unable to copy: %s: %s%n", file, exc);
            }
            return CONTINUE;
        }


        static void copyFile(Path source, Path target, boolean preserve) {
            CopyOption[] options = (preserve)
                    ? new CopyOption[]{COPY_ATTRIBUTES, REPLACE_EXISTING}
                    : new CopyOption[]{REPLACE_EXISTING};
            if (Files.notExists(target)) {
                try {
                    Files.copy(source, target, options);
                } catch (IOException x) {
                    System.err.format("Unable to copy: %s: %s%n", source, x);
                }
            }
        }

    }

并使用以下两行来调用它

String []types = {".java", ".form"};
                TreeCopier tc = new TreeCopier(src.toPath(), dest.toPath(), false, types);
                Files.walkFileTree(src.toPath(), tc);

.java和.form文件类型不会被省略复制并作为String数组参数传递,src.toPath()和dest.toPath()是源和目标路径,false用于指定不保留以前的文件和覆盖它们 如果你想反向,只考虑这些删除不用并用作

if(!correctType)

答案 3 :(得分:0)

查看listFiles课程中的File方法:

Link 1

Link 2

答案 4 :(得分:0)

您可以尝试以下代码:

public class MyFiler implements FileNameFilter{

  bool accept(File file, String name){
     if(name.matches("*.jpg");
  }

}    


public void MassCopy(){
  ArrayList<File> filesToCopy = new ArrayList<File>();
  File sourceDirectory = new File("D:/Pictures/Holidays");
  String[] toCopy = sourceDirectory.list(new MyFilter());
  for(String file : toCopy){
    copyFileToDestination(file);
  }

 }