[Java] Get file list from specified directory
Tags: java
Published: 2024-05-08 16:43:48

## Intro
In this time, I will try getting file list from specified directory.
And I only retrieve the files what has the specific extension.

The root directory path and file extensions are gotten from a JSON file.

### Environments
* Amazon Corretto ver.21.0.3.9.1
* Gradle ver.8.4

## Reading a JSON file
First, I put a JSON file what is named "appsettings.json" into src/main/resources.

#### appsettings.json
```json
{
    "rootDir": "C:/Users/example/OneDrive/Documents/sample",
    "extensions": ["pdf", "xlsx"]
}
```

I will read it and convert to a Java object by Jackson.

#### build.gradle
```java
plugins {
    id 'application'
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
    testImplementation 'junit:junit:4.13.2'
    implementation 'com.google.guava:guava:32.1.1-jre'
}
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}
application {
    mainClass = 'jp.masanori.fileremover.App'
}
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}
```

#### AppSetting.java
```java
package jp.masanori.fileremover.Apps;

public class AppSetting {
    public String rootDir;
    public String[] extensions;
}
```

#### Appsettings.java
```java
package jp.masanori.fileremover.Apps;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jp.masanori.fileremover.App;

public class AppSettings {
    public static AppSetting load() {
        try {
            String filePathText = App.class.getClassLoader().getResource("appsettings.json").getPath();
            // Because the path starts from "/" like "/C:/Users/example/~", I will remove the first "/". 
            Path filePath = Paths.get(filePathText.substring(1, filePathText.length()));
            byte[] fileData = Files.readAllBytes(filePath);
            ObjectMapper objectMapper = new ObjectMapper();
            // Convert
            return objectMapper.readValue(fileData, AppSetting.class);
        }catch(JsonProcessingException ex) {
            System.out.println("[JsonProcessingException] " + ex.getLocalizedMessage());
        } catch(IOException ex) {
            System.out.println("[IOException] " + ex.getLocalizedMessage());
        }
        return null;
    }
}
```

## Getting file list
#### FileController.java
```java
package jp.masanori.fileremover.Files;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jp.masanori.fileremover.Apps.ActionResult;
import jp.masanori.fileremover.Apps.AppSetting;

public class FileController {
    public static ActionResult removeFiles(AppSetting settings) {
        Path rootDirPath = Paths.get(settings.rootDir);
        if(Files.exists(rootDirPath) == false) {
            return ActionResult.getFailed("The root directory was not found");
        }
        Pattern pattern = generateFileExtensionPattern(settings.extensions);
        try (Stream<Path> paths = Files.walk(rootDirPath)) {
            List<Path> targetFilePaths = paths.filter(p -> Files.isDirectory(p) == false)
                .filter(p -> pattern.matcher(p.toString()).find())
                .collect(Collectors.toList());
            for(Path p : targetFilePaths) {
                System.out.println(p.toString());
            }
        } catch(IOException ex) {
            System.out.println(ex.getLocalizedMessage());
            return ActionResult.getFailed("Failed getting file lists");
        }
        return ActionResult.getSucceeded();
    }
    /** Generating a pattern like "\\.pdf|\\.xlsx" */
    private static Pattern generateFileExtensionPattern(String[] fileExtensions) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for(String extension : fileExtensions) {
            if(first) {
                first = false;
            } else {
                sb.append("|");
            }
            sb.append("\\.");
            sb.append(extension);
            sb.append("$");
        }
        return Pattern.compile(sb.toString());
    }
}
```

## Resources
* [Files - Java Platform SE 8](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html)
* [FasterXML/jackson - GitHub](https://github.com/FasterXML/jackson?tab=readme-ov-file)
* [Jackson JSON Java Parser API Example Tutorial - DigitalOcean](https://www.digitalocean.com/community/tutorials/jackson-json-java-parser-api-example-tutorial)
* [Javaでクラスパス上のファイルをPathとして取得する - Qiita](https://qiita.com/suke_masa/items/c26563fccb7c63403a19)