如何在 java 中 'walk' 具有多个文件扩展名的多个目录?
How to 'walk' multiple directories, with multiple file extensions, in java?
这是我的实际代码,效果很好:
String sHomeDir 是我开始扫描的唯一文件夹
String sExt 是搜索的唯一扩展
try (Stream<Path> walk = Files.walk(Paths.get(sHomeDir)))
{
List<String> result = walk.map(x -> x.toString())
.filter(f -> f.endsWith(sExt)).collect(Collectors.toList());
...
} catch (IOException e) {
e.printStackTrace();
}
是否可以重写,以便使用:
- 要扫描的多个文件夹(带子树)
- 要搜索的多个文件扩展名
要处理多个目录,您可以将它们流式传输并将它们平面映射到单个路径流。
要处理多个扩展名,您只需要针对所有扩展名检查文件:
public static List<String> multiWalk
(Collection<String> directories, Collection<String> extensions) {
return directories.stream()
.flatMap(d -> {
try {
return Files.walk(Paths.get(d));
} catch (IOException e) {
return Stream.empty();
}
})
.map(Object::toString)
.filter(f -> extensions.stream().anyMatch(f::endsWith))
.collect(Collectors.toList());
}
我想使用与“File.list()”-方法一起使用的 FilenameFilter。我找到了样本 here.
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
/**
*
* @see:
*
* <h3>setup filter like:</h3>
* private static final ExtensionsFilenameFilter IMAGE_FILTER = <br/>
new ExtensionsFilenameFilter(".png", ".jpg", ".bmp");
*
*/
public class ExtensionsFilenameFilter implements FilenameFilter {
private char[][] extensions;
public ExtensionsFilenameFilter(String... extensions)
{
int length = extensions.length;
this.extensions = new char[length][];
for (String s : extensions)
{
this.extensions[--length] = s.toCharArray();
}
}
@Override
public boolean accept(File dir, String name) {
char[] path = name.toCharArray();
for (char[] extension : extensions)
{
if (extension.length > path.length)
{
continue;
}
int pStart = path.length - 1;
int eStart = extension.length - 1;
boolean success = true;
for (int i = 0; i <= eStart; i++)
{
if ((path[pStart - i] | 0x20) != (extension[eStart - i] | 0x20))
{
success = false;
break;
}
}
if (success)
return true;
}
return false;
}
}
然后我通过以下方式遍历根路径下的所有路径:
public void walkList(String path) throws IOException {
List<String> imagefiles = new ArrayList<>();
Files.walk(Paths.get(path))
.filter(Files::isDirectory)
.map(walkPath -> {
List<String> pathnames = new ArrayList<>();
List<String> filenames = Arrays.asList(walkPath.toFile().list(new ExtensionsFilenameFilter("jpg", "tif", "bmp")));
filenames.forEach(fn -> {
pathnames.add(String.format("%s/%s", walkPath.toFile().toString(), fn));
});
return pathnames;
})
.forEach(imagefiles::addAll);
imagefiles.forEach(System.out::println);
}
这是我的实际代码,效果很好:
String sHomeDir 是我开始扫描的唯一文件夹
String sExt 是搜索的唯一扩展
try (Stream<Path> walk = Files.walk(Paths.get(sHomeDir)))
{
List<String> result = walk.map(x -> x.toString())
.filter(f -> f.endsWith(sExt)).collect(Collectors.toList());
...
} catch (IOException e) {
e.printStackTrace();
}
是否可以重写,以便使用:
- 要扫描的多个文件夹(带子树)
- 要搜索的多个文件扩展名
要处理多个目录,您可以将它们流式传输并将它们平面映射到单个路径流。 要处理多个扩展名,您只需要针对所有扩展名检查文件:
public static List<String> multiWalk
(Collection<String> directories, Collection<String> extensions) {
return directories.stream()
.flatMap(d -> {
try {
return Files.walk(Paths.get(d));
} catch (IOException e) {
return Stream.empty();
}
})
.map(Object::toString)
.filter(f -> extensions.stream().anyMatch(f::endsWith))
.collect(Collectors.toList());
}
我想使用与“File.list()”-方法一起使用的 FilenameFilter。我找到了样本 here.
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
/**
*
* @see:
*
* <h3>setup filter like:</h3>
* private static final ExtensionsFilenameFilter IMAGE_FILTER = <br/>
new ExtensionsFilenameFilter(".png", ".jpg", ".bmp");
*
*/
public class ExtensionsFilenameFilter implements FilenameFilter {
private char[][] extensions;
public ExtensionsFilenameFilter(String... extensions)
{
int length = extensions.length;
this.extensions = new char[length][];
for (String s : extensions)
{
this.extensions[--length] = s.toCharArray();
}
}
@Override
public boolean accept(File dir, String name) {
char[] path = name.toCharArray();
for (char[] extension : extensions)
{
if (extension.length > path.length)
{
continue;
}
int pStart = path.length - 1;
int eStart = extension.length - 1;
boolean success = true;
for (int i = 0; i <= eStart; i++)
{
if ((path[pStart - i] | 0x20) != (extension[eStart - i] | 0x20))
{
success = false;
break;
}
}
if (success)
return true;
}
return false;
}
}
然后我通过以下方式遍历根路径下的所有路径:
public void walkList(String path) throws IOException {
List<String> imagefiles = new ArrayList<>();
Files.walk(Paths.get(path))
.filter(Files::isDirectory)
.map(walkPath -> {
List<String> pathnames = new ArrayList<>();
List<String> filenames = Arrays.asList(walkPath.toFile().list(new ExtensionsFilenameFilter("jpg", "tif", "bmp")));
filenames.forEach(fn -> {
pathnames.add(String.format("%s/%s", walkPath.toFile().toString(), fn));
});
return pathnames;
})
.forEach(imagefiles::addAll);
imagefiles.forEach(System.out::println);
}