Capture name of files in directory

4

The following method takes the name of the files of a certain directory and displays them on the screen, the problem is that .listfiles() returns the number of bytes and not the number of files, although it shows the files name just having an ArrayIndexOutOfBoundsException error since I'm trying to access values that do not exist. How can I get the name of the directory files without errors?

   public static void getImgs(String path){
    File file = new File(path);
    File[] arquivos = file.listFiles();

    for (int i=0; i<file.length(); i++) {
        System.out.println(arquivos[i]);
    }
}
    
asked by anonymous 26.02.2016 / 16:33

5 answers

5

The easiest way to avoid this exception is to use a foreach. Example:

public static void getImgs(String path){
    File file = new File(path);
    File[] arquivos = file.listFiles();

    for (File arquivo : arquivos) {
        System.out.println(arquivo);
    }
}

In% with% the JVM itself is responsible for iterating through the files in its list, and it guarantees that you will never have a for (File arquivo : arquivos) that does not exist in the array (but the variable itself depends on your list, cases arquivo could contain the value arquivo , for example).

    
26.02.2016 / 16:40
4

Whenever possible, prefer the new Java 8 API that uses the Path .

For example, you can list the files in a directory like this:

Files.walk(Paths.get("/tmp"), 1, FileVisitOption.FOLLOW_LINKS)
        .forEach(path -> System.out.printf("%s%n", path.toAbsolutePath().toString()));

The first parameter is the directory itself, which is a Path built using the Paths.get() method. Note that this method can receive an arbitrary amount of parameters, so you no longer have to worry about slashes, because you can always specify each component of the path in a separate parameter.

The second argument defines whether the routine will read subdirectories. In this case, 1 (one) means that I'm only listing the current directory. To read all subdirectories, use Integer.MAX_VALUE .

The third parameter receives FileVisitOption.FOLLOW_LINKS to tell Java that it should consider the shortcuts as used in linux / unix. I consider it important to always use this parameter.

The walk method returns a Stream , which is the Java 8 functional way of traversing a sequence of elements. The forEach allows executing a command for each element of Stream , which in this case prints the absolute path inside the lambda expression.

If you want to, for example, filter the file types, you can do this:

Files.walk(Paths.get("/tmp"), 1, FileVisitOption.FOLLOW_LINKS)
        .filter(path -> path.toString().endsWith(".log"))
        .forEach(path -> System.out.printf("%s%n", path.toAbsolutePath().toString()));

The difference here is the filter that leaves in the Stream all paths ending with .log . The syntax may not be easy at first, but what the code does is pretty obvious.

Finally, there is a shortcut to already filtering the files at the time of listing, the Files.find method. Example:

Files.find(Paths.get("/tmp"), 1,
        (path, attributes) -> attributes.isRegularFile() && path.toString().endsWith(".log"),
        FileVisitOption.FOLLOW_LINKS
).forEach(path -> System.out.println(path.toAbsolutePath()));

This method is more efficient and allows you to easily access the attributes of the file. In case, I'm checking if it's a normal file and not a directory or symbol using attributes.isRegularFile() .

    
29.02.2016 / 01:40
3

Another approach is to use the Apache Commons IO library. It has several utilitarian methods.

For example, the listFiles(java.io.File, java.lang.String[], boolean) ". Where you define a root directory, a String array with extensions, and a boolean indicating whether the search should be recursive (in subdirectories). At the end you can manipulate the resulting Collection .

    
26.02.2016 / 17:22
3

You can use DirectoryStream<T> where the generic type is a Path :

// C:\Users\Fulano\Desktop
Path diretorio = Paths.get("C:", "Users", "Fulano", "Desktop");

try (DirectoryStream<Path> stream = Files.newDirectoryStream(diretorio){
  for(Path path : stream)
     System.out.println(path.getFileName());
}

If you need to list files with specific extensions, use the second method parameter Files#newDirectoryStream() passing a string with the filtered extensions template:

// Listando todos os arquivos com extensão ".java"
try (DirectoryStream<Path> stream = Files.newDirectoryStream(diretorio, "*.java"){
  for(Path path : stream)
     System.out.println(path.getFileName());
}
// Listando arquivos com extensão .jpg, .gif e .png     
try (DirectoryStream<Path> stream = Files.newDirectoryStream(diretorio, "*.{jpg,gif,png}"){
  for(Path path : stream)
     System.out.println(path.getFileName());
}

If you want to go beyond and also get the files that are in folders in the same directory, I found in this answer < sup> [en] a solution using recursion.

    
29.02.2016 / 02:41
-1

Here is a simple way that helped me and can help you too:

Components used:

  • 01 JTextField with the name "txtCaminho";
  • 01 JButton with the name "btnSearch";
  • JFileChooser fc = new JFileChooser();
    fc.showOpenDialog(this);
    
    try {
    
      File arquivo = fc.getSelectedFile();
      String caminho = arquivo.getAbsolutePath();
      caminho = caminho.replace('\', '/');
    
      // aqui eu mostro numa JTextField o caminho absoluto
      txtLocal.setText(caminho);                 
    
      String nomeArq = new File(caminho).getName();
      System.out.println(nomeArq);
    
    } catch (Exception e) {
      System.out.println("Deu tudo errado...);
    }
    
        
    29.11.2016 / 17:58