提问人:Rostnik5522 提问时间:11/17/2023 最后编辑:Rostnik5522 更新时间:11/18/2023 访问量:87
尝试获取扩展名为“java”的最大尺寸的文件名
Trying to get file name with the largest size with extension "java"
问:
我用来列出目录中的所有文件,包括所有级别的子目录,并带有以“java”结尾的文件过滤器。Files.walk
public static void main(String[] args) throws IOException {
List<String> files = findFiles(Paths.get("C:\\project"),"java");
files.forEach(System.out::println);
public static List<String> findFiles(Path path, String extension) throws IOException {
List<String> result;
try (Stream<Path> walk = Files.walk(path)) {
result = walk.filter(p -> !Files.isDirectory(p))
.map(p -> p.toString().toLowerCase())
.filter(f -> f.endsWith(extension))
.collect(Collectors.toList());
}
return result;
}
现在,我希望将文件的字符串列表转换为另一种方法,以查找具有最大大小的文件名。
我不知道该怎么做,也许把它放在字符串列表中是个坏主意。 所以我正在寻求帮助,或者可能以不同的方式解决这个问题。
答:
试试这个:
public static void main( final String... args ) throws IOException
{
final var file = findLargestFile( Paths.get( "C:\\project" ),"java" );
System.out.println( file.getAbsolutePath() );
}
public static final File findLargestFile( final Path path, final String extension ) throws IOException
{
try( final var walk = Files.walk( path ) )
{
return walk.filter( p -> !Files.isDirectory( p ) )
.map( Path::toFile )
.filter( f -> f.getName().toLowerCase( ROOT ).endsWith( extension ) )
.max( comparingLong( File::length ) )
.orElse( null );
}
}
findLargestFile()
消除没有正确扩展名的文件,然后获取剩余文件中最大的文件并返回该文件,或者如果源文件夹为空。null
如果要取回 的实例,它可能如下所示:Path
public static final Path findLargestPath( final Path path, final String extension ) throws IOException
{
final ToLongFunction<Path> size = p ->
{
var result = 0L;
try
{
result = Files.size( p );
}
catch( final IOException ignored ) {}
return result;
};
final Predicate<Path> validExtension = p -> p.getName( p.getNameCount() - 1 )
.toString()
.toLowerCase( ROOT )
.endsWith( extension );
try( final var walk = Files.walk( path ) )
{
return walk.filter( p -> !Files.isDirectory( p ) )
.filter( validExtension )
.max( comparingLong( size ) )
.orElse( null );
}
}
与其吞下 ,不如把它包成一个 然后扔掉。IOException
UncheckedIOException
评论
.filter( p -> p.getName()
.toLowerCase( ROOT )
.toLowerCase()
File::getName
String::toLowerCase
String::toUpperCase
Files::walk
Stream<Path>
Stream<File>
在下面的代码中,方法遍历目录树,从 dir 开始,并过滤文件扩展名为findFiles
.java
然后,它按文件的大小从大到小对文件进行排序。
然后,它将文件收集到 其中 [map] 键是文件的路径,[map] 值是文件的大小。 维护向其添加条目的顺序。由于在将条目添加到 之前先对条目进行排序,因此第一个条目是具有最大大小的文件。LinkedHashMap
LinkedHashMap
LinkedHashMap
请注意,实现了 [interface] – 它是在 Java 21 中添加的。 声明返回第一个条目的方法,该条目是具有最大大小的文件。LinkedHashMap
SequencedMap
SequencedMap
firstEntry()
最后,该方法打印出最大文件的名称和大小。
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SequencedMap;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Greatest {
private static void findFiles(Path dir, String ext) throws IOException {
// Map key is path to the file.
Function<Path, Path> keyMapper = path -> path;
// Map value is file size.
Function<Path, Long> valueMapper = path -> {
try {
return Files.size(path);
}
catch (IOException xIo) {
throw new UncheckedIOException(xIo);
}
};
// If two files have the same path (shouldn't occur), return the size
// of the first file.
BinaryOperator<Long> mergeFunction = (s1, s2) -> s1;
// Collect the stream elements into a 'LinkedHashMap'
Supplier<Map<Path, Long>> mapFactory = () -> new LinkedHashMap<Path, Long>();
try (Stream<Path> files = Files.walk(dir)) {
System.out.println(((SequencedMap<Path, Long>) files.filter(p -> Files.isRegularFile(p) &&
p.getFileName().toString().endsWith(ext))
.sorted(Comparator.comparing((Path p) -> {
try {
return Files.size(p);
}
catch (IOException x) {
throw new UncheckedIOException(x);
}
}).reversed())
.collect(Collectors.toMap(keyMapper,
valueMapper,
mergeFunction,
mapFactory))).firstEntry());
};
}
public static void main(String[] args) {
Path dir;
if (args.length > 0) {
dir = Paths.get(args[0]);
}
else {
dir = Paths.get(System.getProperty("user.dir"));
}
String ext;
if (args.length > 1) {
ext = args[1];
}
else {
ext = ".java";
}
try {
findFiles(dir, ext);
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
"...我希望将文件的字符串列表转换为另一种方法,以查找具有最大大小的文件名。..."
多个文件的大小可能相同。
利用带有 TreeMap 的 Collectors#groupingBy 方法仅返回最大值。
List<String> findFiles(Path path, String extension) throws IOException {
List<String> result;
try (Stream<Path> walk = Files.walk(path)) {
result
= walk.filter(p -> !Files.isDirectory(p) && p.toString().endsWith(extension))
.collect(
Collectors.groupingBy(
x -> x.toFile().length(),
TreeMap::new,
Collectors.mapping(Path::toString, Collectors.toList())
))
.lastEntry()
.getValue();
}
return result;
}
例如,我有一个包含三个文件的目录,“a.txt”、“ab.txt”和“abc.txt”。
大小分别为 2、3 和 4 字节。
还有一个子目录,其中包含两个文件,“b.txt”和“bc.txt”,大小分别为 3 和 4 字节。
输出
files/abc.txt
files/more/bc.txt
评论
.java
A.java
Xyz.java
Xyz