Is it possible to copy directory names without copying their contents?

Asked

Viewed 172 times

3

Some time ago I did this question about recursive search in folders, and now I need to adapt to a different condition.

I need to copy only the names of the subfolders from a higher folder to a third one, but without copying the most internal files and folders, that is, I need to "clone" the first level subfolders without taking their content along.

ex.:

-Pasta root
    |-subpasta1✅
        |-sub-subpasta1(esse nivel não pode ser copiado)
    |-subpasta2 ✅
    |-subpasta3✅
    |-subpasta4✅
    ...
    |-subpastaN✅

I’m currently using a suggested method in the linked question to filter files:

private static List<File> filtrarArquivos(File source, String pattern) throws IOException {
    List<File> fileList = new ArrayList<>();

    Files.walk(source.toPath()).forEach(arquivo -> {

        if (arquivo.getFileName().toString().matches(pattern)) {
            fileList.add(arquivo.toFile());
        }
    });

    return fileList;
}

It is possible to adapt this method to the reported problem?

2 answers

4


By changing your method you can do as follows:

private static List<File> filtrarDiretorios(File origem) throws IOException {
  List<File> diretorios = new ArrayList<>();

  Files.list(origem.toPath())
          .map(arquivo -> arquivo.toFile())
          .filter(arquivo -> arquivo.isDirectory())
          .forEach(diretorios::add);

  return diretorios;
}

We use the Steram#map to convert the contents of the list returned by Path#list in a Stream of File. We use the method Stream#filter of Stream resulting to filter only the File which are a directory with the function File#isDirectory and we go through the resulting records with Stream#forEach to add them to the List that will return from the method filtrarArquivos.

You can apply the above method as follows (Completing the copy of folders):

private static void copiarDiretorios(File origem, File destino) throws IOException {
  List<File> diretorios;

  diretorios = filtrarDiretorios(origem);
  diretorios.forEach(diretorio -> copiar(destino, diretorio));
}

private static void copiar(File destino, File diretorio) {
  File novo;

  novo = new File(destino, diretorio.getName());
  novo.mkdirs();
}
  • 1

    But won’t that work recursively, like the question? Because what would get in the way of me now copying the first level of directories is the recursion sweeping out other subfolder levels.

  • @diegofm changed to respond without recursiveness

  • 1

    I adapted in a different way but the base I used the same filtrardiretorios method, worth :D

  • @diegofm avail. Just one thing, maybe this method of filtrarDiretorios could return only one List<String>. I don’t know if it would have much impact this change, but I think it makes more sense

  • 1

    I thought about it too but I check some other things that File is more viable than String, so I returned File, to facilitate.

3

The following method copies all direct child files from a source folder to a destination folder:

public static final List<File> copiarSubdiretorios(File origem, File destino) throws IOException {
    List<File> arquivos = new ArrayList<>();
    for(File arquivo : origem.listFiles(File::isDirectory)) {
        File novoArquivo = new File(destino.getAbsolutePath() + "/" + arquivo.getName());
        novoArquivo.mkdirs();
        arquivos.add(novoArquivo);
    }
    return arquivos;
}

Edit:

If you only want the name of the subfolders do the following:

public static final List<String> listarSubdiretorios(File root) {
    return Arrays.asList(root.listFiles(File::isDirectory))
                .stream()
                .map(File::getName)
                .collect(Collectors.toList());
}

If you want objects File representing the directories:

public static final List<File> listarSubdiretorios(File root) {
    return Arrays.asList(root.listFiles(File::isDirectory));
}
  • This way it does not serve me, because the source is the root folder Path, and I do not want to use the same method to do everything. Just receive the root folder path and return me a list of the first level directories for me to create in another folder, as in the example.

  • @diegofm edited the answer.

  • Thanks, this method worked too, only I had already applied the other. But there is an option as alternative :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.