mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
PathUtil增加loopFiles重载,可选是否追踪软链
This commit is contained in:
parent
eeed094f92
commit
5af0894911
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.core.io.file;
|
package org.dromara.hutool.core.io.file;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.collection.set.SetUtil;
|
||||||
import org.dromara.hutool.core.io.IORuntimeException;
|
import org.dromara.hutool.core.io.IORuntimeException;
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.util.CharsetUtil;
|
import org.dromara.hutool.core.util.CharsetUtil;
|
||||||
@ -23,6 +24,7 @@ import java.nio.file.attribute.BasicFileAttributes;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NIO中Path对象操作封装
|
* NIO中Path对象操作封装
|
||||||
@ -71,11 +73,26 @@ public class PathUtil {
|
|||||||
* @since 5.4.1
|
* @since 5.4.1
|
||||||
*/
|
*/
|
||||||
public static List<File> loopFiles(final Path path, final int maxDepth, final FileFilter fileFilter) {
|
public static List<File> loopFiles(final Path path, final int maxDepth, final FileFilter fileFilter) {
|
||||||
|
return loopFiles(path, maxDepth, false, fileFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归遍历目录以及子目录中的所有文件<br>
|
||||||
|
* 如果提供path为文件,直接返回过滤结果
|
||||||
|
*
|
||||||
|
* @param path 当前遍历文件或目录
|
||||||
|
* @param maxDepth 遍历最大深度,-1表示遍历到没有目录为止
|
||||||
|
* @param isFollowLinks 是否跟踪软链(快捷方式)
|
||||||
|
* @param fileFilter 文件过滤规则对象,选择要保留的文件,只对文件有效,不过滤目录,null表示接收全部文件
|
||||||
|
* @return 文件列表
|
||||||
|
* @since 5.4.1
|
||||||
|
*/
|
||||||
|
public static List<File> loopFiles(final Path path, final int maxDepth, final boolean isFollowLinks, final FileFilter fileFilter) {
|
||||||
final List<File> fileList = new ArrayList<>();
|
final List<File> fileList = new ArrayList<>();
|
||||||
|
|
||||||
if (null == path || !Files.exists(path)) {
|
if (!exists(path, isFollowLinks)) {
|
||||||
return fileList;
|
return fileList;
|
||||||
} else if (!isDirectory(path)) {
|
} else if (!isDirectory(path, isFollowLinks)) {
|
||||||
final File file = path.toFile();
|
final File file = path.toFile();
|
||||||
if (null == fileFilter || fileFilter.accept(file)) {
|
if (null == fileFilter || fileFilter.accept(file)) {
|
||||||
fileList.add(file);
|
fileList.add(file);
|
||||||
@ -83,7 +100,7 @@ public class PathUtil {
|
|||||||
return fileList;
|
return fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
walkFiles(path, maxDepth, new SimpleFileVisitor<Path>() {
|
walkFiles(path, maxDepth, isFollowLinks, new SimpleFileVisitor<Path>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) {
|
public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) {
|
||||||
@ -119,14 +136,28 @@ public class PathUtil {
|
|||||||
* @see Files#walkFileTree(Path, java.util.Set, int, FileVisitor)
|
* @see Files#walkFileTree(Path, java.util.Set, int, FileVisitor)
|
||||||
* @since 4.6.3
|
* @since 4.6.3
|
||||||
*/
|
*/
|
||||||
public static void walkFiles(final Path start, int maxDepth, final FileVisitor<? super Path> visitor) {
|
public static void walkFiles(final Path start, final int maxDepth, final FileVisitor<? super Path> visitor) {
|
||||||
|
walkFiles(start, maxDepth, false, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遍历指定path下的文件并做处理
|
||||||
|
*
|
||||||
|
* @param start 起始路径,必须为目录
|
||||||
|
* @param maxDepth 最大遍历深度,-1表示不限制深度
|
||||||
|
* @param visitor {@link FileVisitor} 接口,用于自定义在访问文件时,访问目录前后等节点做的操作
|
||||||
|
* @param isFollowLinks 是否追踪到软链对应的真实地址
|
||||||
|
* @see Files#walkFileTree(Path, java.util.Set, int, FileVisitor)
|
||||||
|
* @since 5.8.23
|
||||||
|
*/
|
||||||
|
public static void walkFiles(final Path start, int maxDepth, final boolean isFollowLinks, final FileVisitor<? super Path> visitor) {
|
||||||
if (maxDepth < 0) {
|
if (maxDepth < 0) {
|
||||||
// < 0 表示遍历到最底层
|
// < 0 表示遍历到最底层
|
||||||
maxDepth = Integer.MAX_VALUE;
|
maxDepth = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Files.walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), maxDepth, visitor);
|
Files.walkFileTree(start, getFileVisitOption(isFollowLinks), maxDepth, visitor);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
throw new IORuntimeException(e);
|
throw new IORuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -238,8 +269,7 @@ public class PathUtil {
|
|||||||
if (null == path) {
|
if (null == path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
return Files.isDirectory(path, getLinkOptions(isFollowLinks));
|
||||||
return Files.isDirectory(path, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -323,9 +353,8 @@ public class PathUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
|
||||||
try {
|
try {
|
||||||
return Files.readAttributes(path, BasicFileAttributes.class, options);
|
return Files.readAttributes(path, BasicFileAttributes.class, getLinkOptions(isFollowLinks));
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
throw new IORuntimeException(e);
|
throw new IORuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -497,8 +526,7 @@ public class PathUtil {
|
|||||||
if (null == path) {
|
if (null == path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
return Files.isRegularFile(path, getLinkOptions(isFollowLinks));
|
||||||
return Files.isRegularFile(path, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -535,8 +563,7 @@ public class PathUtil {
|
|||||||
if (null == path) {
|
if (null == path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
return Files.exists(path, getLinkOptions(isFollowLinks));
|
||||||
return Files.exists(path, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -572,7 +599,7 @@ public class PathUtil {
|
|||||||
* @return 实际路径
|
* @return 实际路径
|
||||||
* @throws IORuntimeException IO异常,如文件不存在等
|
* @throws IORuntimeException IO异常,如文件不存在等
|
||||||
*/
|
*/
|
||||||
public static Path toRealPath(Path path) throws IORuntimeException{
|
public static Path toRealPath(Path path) throws IORuntimeException {
|
||||||
if (null != path) {
|
if (null != path) {
|
||||||
try {
|
try {
|
||||||
path = path.toRealPath();
|
path = path.toRealPath();
|
||||||
@ -663,11 +690,35 @@ public class PathUtil {
|
|||||||
} else {
|
} else {
|
||||||
return Files.createTempFile(mkdir(dir), prefix, suffix);
|
return Files.createTempFile(mkdir(dir), prefix, suffix);
|
||||||
}
|
}
|
||||||
} catch (final IOException ioex) { // fixes java.io.WinNTFileSystem.createFileExclusively access denied
|
} catch (final IOException ioex) {
|
||||||
|
// fixes java.io.WinNTFileSystem.createFileExclusively access denied
|
||||||
if (++exceptionsCount >= 50) {
|
if (++exceptionsCount >= 50) {
|
||||||
throw new IORuntimeException(ioex);
|
throw new IORuntimeException(ioex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建是否追踪软链的选项
|
||||||
|
*
|
||||||
|
* @param isFollowLinks 是否追踪软链
|
||||||
|
* @return 选项
|
||||||
|
* @since 5.8.23
|
||||||
|
*/
|
||||||
|
public static LinkOption[] getLinkOptions(final boolean isFollowLinks) {
|
||||||
|
return isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建是否追踪软链的选项
|
||||||
|
*
|
||||||
|
* @param isFollowLinks 是否追踪软链
|
||||||
|
* @return 选项
|
||||||
|
* @since 5.8.23
|
||||||
|
*/
|
||||||
|
public static Set<FileVisitOption> getFileVisitOption(final boolean isFollowLinks) {
|
||||||
|
return isFollowLinks ? EnumSet.of(FileVisitOption.FOLLOW_LINKS) :
|
||||||
|
EnumSet.noneOf(FileVisitOption.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user