背景
多数のファイルに対してJavaで操作が必要な時に、ターミナルのfind
コマンドなどでリストアップしてからJavaに渡すよりも、リストアップの部分もJavaで実装したほうが、処理が一貫して簡単なのでこのコードを書いた。
コードの概要
このプログラムは、ディレクトリ名と拡張子を引数として、指定したディレクトリとそれより下層のディレクトリを探索し、指定した拡張子のファイルをArrayList
に保存する。ここではiTunesのフォルダにあるm4aファイルを探して、リストに保存する。
上のコードではJava8で新しく導入されたラムダ式(Lambda Expressions
)とストリーム(Stream
)を使っている。ラムダ式とストリームを使っていないコードは下を参照。(Java8より古いJavaでも動くかも。。)
Java 8以降
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Utils {
public static void main(String[] args) throws IOException {
// To list up m4a files in iTunes directory
Path rootDir = Paths.get(System.getProperty("user.home"), "Music", "iTunes");
String extension = "m4a";
// for standard inputs
if (args.length == 2) {
rootDir = Paths.get(args[0]);
extension = args[1];
} else if (args.length != 0){
System.err.println("Error: set correct args.");
}
if (!Pattern.matches("^[0-9a-zA-Z]+$", extension)) {
System.err.println("Error: set correct extension. (only alphabet and numeric)");
} else {
ArrayList<File> fileList = listUpFiles(rootDir, extension);
for (File file : fileList) {
System.out.println(file.getAbsolutePath());
}
System.out.println(fileList.size());
}
}
/**
* list up files with specified file extension (extension)
* under the specified directory (rootDir) recursively.
* @param rootDir : root directory
* @param extension : string needs to be contained as file extension
* @return : list of files
*/
public static ArrayList<File> listUpFiles(Path rootDir, String extension){
String extensionPattern = "." + extension.toLowerCase();
final ArrayList<File> fileList = new ArrayList();
try (final Stream<Path> pathStream = Files.walk(rootDir)) {
pathStream
.map(path -> Path::toFile)
.filter(file -> !file.isDirectory())
.filter(file -> file.getName().toLowerCase().endsWith(extensionPattern))
.forEach(fileList::add);
} catch (final IOException e) {
e.printStackTrace();
}
return (fileList);
}
}
ラムダ式とストリームを使っていないコード
import java.io.File;
import java.util.regex.Pattern;
import java.util.ArrayList;
public class UtilsOld {
public static void main(String[] args) {
// To list up m4a files in iTunes directory
String rootDirName = System.getProperty("user.home") + java.io.File.separator +
"Music" + java.io.File.separator + "iTunes";
String extension = "m4a";
// for standard input
if (args.length == 2) {
rootDirName = args[0];
extension = args[1];
} else if (args.length != 0){
System.err.println("Error: set correct args.");
}
if (!Pattern.matches("^[0-9a-zA-Z]+$", extension)) {
System.err.println("Error: set correct extension. (only alphabet and numeric)");
} else {
String extensionPattern = "." + extension.toLowerCase();
ArrayList<File> fileList = new ArrayList();
fileList = listUpFiles(rootDirName, extensionPattern, fileList);
for (File file : fileList) {
System.out.println(file.getAbsolutePath());
}
System.out.println(fileList.size());
}
}
/**
* list up files with specified file extension (ext)
* under the specified directory (rootDirName) recursively.
*
* @param rootDirName : root directory name
* @param extensionPattern : regular expression pattern of file extension
* @param fileArrayList : ArrayList to store files
* @return : return fileArrayList
*/
public static ArrayList listUpFiles(String rootDirName, String extensionPattern, ArrayList<File> fileArrayList){
File rootDir = new File(rootDirName);
File[] listOfFiles = rootDir.listFiles();
assert listOfFiles != null;
for (File item : listOfFiles) {
if (item.isDirectory()) {
fileArrayList = listUpFiles(item.getAbsolutePath(), extensionPattern, fileArrayList);
} else if (item.isFile()) {
String fileName = item.getName().toLowerCase();
if (fileName.endsWith(extensionPattern)) {
fileArrayList.add(item);
}
}
}
return(fileArrayList);
}
}
参考
saka1029さんのコメント
https://www.javacodegeeks.com/2014/05/playing-with-java-8-lambdas-paths-and-files.html