Как скопировать все файлы с определенными расширениями из каталога и подкаталогов?

#java #java-io

#java #java-io

Вопрос:

Я знаю, как скопировать файл из одного каталога в другой, мне нужна помощь в копировании файла с расширением .jpg или .doc.

Так, например.

Скопируйте все файлы из D:/Pictures/Holidays

Сканирование всех папок по указанному выше пути и передача всех файлов jpg в указанное место назначения.

Ответ №1:

Это работает, но метод file ‘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();
        }
    }
}
  

Ответ №2:

Используйте a 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;
    }
}
  

Комментарии:

1. Приведенный выше код действительно помог, возможно ли, что вы могли бы прокомментировать его, чтобы я мог лучше понять его, поскольку я новичок в Java, мне бы очень помогло, если бы вы могли.

2. Слишком занят. Какие части вы не понимаете?

3. я понимаю, я понял это. Еще раз спасибо !.

Ответ №3:

Для этого используйте следующий класс file walker tree

 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 amp;amp; 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 array, src.toPath() и dest .toPath() — это пути источника и назначения, false используется для указания не сохранять предыдущие файлы и перезаписывать их
, если вы хотите обратного, то есть рассматривать только эти remove not и использовать как

 if(!correctType)
  

Ответ №4:

Взгляните на listFiles методы из File класса:

Ссылка 1

Ссылка 2

Ответ №5:

Вы могли бы попробовать этот код:

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

 }