简体   繁体   中英

How to copy all files with certain extensions from a directory and sub directories?

I know how to copy a file from one directory to another, what I would like help on is copy a file with .jpg or .doc extension.

So for example.

Copy all files from D:/Pictures/Holidays

Scanning all folders in the above path and transfer all jpg's to a destination provided.

This works, but the file 'copy(File file, File outputFolder)' method could be enhanced for large files:

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();
        }
    }
}

Use following file walker tree class to do that

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);
                }
            }
        }

    }

and call it using following two lines

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

.java and .form file types are not omitted to copy and passed as String array parameter, src.toPath() and dest.toPath() are source and destination paths, false is used to specify not to preserve previous files and overwrite them if you want reverse that is to consider only these remove not and use as

if(!correctType)

Use a FileFilter when listing files.

In this case, the filter would select directories and any file type of interest.


Here is a quick example (crudely hacked out of another project) of gaining a list of types of files in a directory structure.

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;
    }
}

Take a look at the listFiles methods from the File class:

Link 1

Link 2

You could try this code:

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);
  }

 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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