FileUtil.java
net.minecraft.util.FileUtil
信息
- 全限定名:net.minecraft.util.FileUtil
- 类型:public class
- 包:net.minecraft.util
- 源码路径:src/main/java/net/minecraft/util/FileUtil.java
- 起始行号:L17
- 职责:
TODO
字段/常量
-
COPY_COUNTER_PATTERN- 类型:
Pattern - 修饰符:
private static final - 源码定位:
L18 - 说明:
TODO
- 类型:
-
MAX_FILE_NAME- 类型:
int - 修饰符:
private static final - 源码定位:
L19 - 说明:
TODO
- 类型:
-
RESERVED_WINDOWS_FILENAMES- 类型:
Pattern - 修饰符:
private static final - 源码定位:
L20 - 说明:
TODO
- 类型:
-
STRICT_PATH_SEGMENT_CHECK- 类型:
Pattern - 修饰符:
private static final - 源码定位:
L21 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
- 无
方法
下面的方法块按源码顺序生成。
public static String sanitizeName(String baseName) @ L23
- 方法名:sanitizeName
- 源码定位:L23
- 返回类型:String
- 修饰符:public static
参数:
- baseName: String
说明:
TODO
public static String findAvailableName(Path baseDir, String baseName, String suffix) @ L31
- 方法名:findAvailableName
- 源码定位:L31
- 返回类型:String
- 修饰符:public static
参数:
- baseDir: Path
- baseName: String
- suffix: String
说明:
TODO
public static boolean isPathPortable(Path path) @ L73
- 方法名:isPathPortable
- 源码定位:L73
- 返回类型:boolean
- 修饰符:public static
参数:
- path: Path
说明:
TODO
public static boolean isPathPartPortable(String name) @ L83
- 方法名:isPathPartPortable
- 源码定位:L83
- 返回类型:boolean
- 修饰符:public static
参数:
- name: String
说明:
TODO
public static String getFullResourcePath(String filename) @ L87
- 方法名:getFullResourcePath
- 源码定位:L87
- 返回类型:String
- 修饰符:public static
参数:
- filename: String
说明:
TODO
public static String normalizeResourcePath(String filename) @ L91
- 方法名:normalizeResourcePath
- 源码定位:L91
- 返回类型:String
- 修饰符:public static
参数:
- filename: String
说明:
TODO
public static DataResult<List<String>> decomposePath(String path) @ L95
- 方法名:decomposePath
- 源码定位:L95
- 返回类型:DataResult<List
> - 修饰符:public static
参数:
- path: String
说明:
TODO
public static Path resolvePath(Path root, List<String> segments) @ L135
- 方法名:resolvePath
- 源码定位:L135
- 返回类型:Path
- 修饰符:public static
参数:
- root: Path
- segments: List
说明:
TODO
private static boolean containsAllowedCharactersOnly(String segment) @ L153
- 方法名:containsAllowedCharactersOnly
- 源码定位:L153
- 返回类型:boolean
- 修饰符:private static
参数:
- segment: String
说明:
TODO
public static boolean isValidPathSegment(String segment) @ L157
- 方法名:isValidPathSegment
- 源码定位:L157
- 返回类型:boolean
- 修饰符:public static
参数:
- segment: String
说明:
TODO
public static void validatePath(String... path) @ L161
- 方法名:validatePath
- 源码定位:L161
- 返回类型:void
- 修饰符:public static
参数:
- path: String…
说明:
TODO
public static void createDirectoriesSafe(Path dir) @ L173
- 方法名:createDirectoriesSafe
- 源码定位:L173
- 返回类型:void
- 修饰符:public static
参数:
- dir: Path
说明:
TODO
static boolean isEmptyPath(Path path) @ L177
- 方法名:isEmptyPath
- 源码定位:L177
- 返回类型:boolean
- 修饰符:static
参数:
- path: Path
说明:
TODO
代码
public class FileUtil {
private static final Pattern COPY_COUNTER_PATTERN = Pattern.compile("(<name>.*) \\((<count>\\d*)\\)", 66);
private static final int MAX_FILE_NAME = 255;
private static final Pattern RESERVED_WINDOWS_FILENAMES = Pattern.compile(".*\\.|(?:COM|CLOCK\\$|CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\\..*)?", 2);
private static final Pattern STRICT_PATH_SEGMENT_CHECK = Pattern.compile("[-._a-z0-9]+");
public static String sanitizeName(String baseName) {
for (char replacer : SharedConstants.ILLEGAL_FILE_CHARACTERS) {
baseName = baseName.replace(replacer, '_');
}
return baseName.replaceAll("[./\"]", "_");
}
public static String findAvailableName(Path baseDir, String baseName, String suffix) throws IOException {
baseName = sanitizeName(baseName);
if (!isPathPartPortable(baseName)) {
baseName = "_" + baseName + "_";
}
Matcher matcher = COPY_COUNTER_PATTERN.matcher(baseName);
int count = 0;
if (matcher.matches()) {
baseName = matcher.group("name");
count = Integer.parseInt(matcher.group("count"));
}
if (baseName.length() > 255 - suffix.length()) {
baseName = baseName.substring(0, 255 - suffix.length());
}
while (true) {
String nameToTest = baseName;
if (count != 0) {
String countSuffix = " (" + count + ")";
int length = 255 - countSuffix.length();
if (baseName.length() > length) {
nameToTest = baseName.substring(0, length);
}
nameToTest = nameToTest + countSuffix;
}
nameToTest = nameToTest + suffix;
Path fullPath = baseDir.resolve(nameToTest);
try {
Path created = Files.createDirectory(fullPath);
Files.deleteIfExists(created);
return baseDir.relativize(created).toString();
} catch (FileAlreadyExistsException var8) {
count++;
}
}
}
public static boolean isPathPortable(Path path) {
for (Path part : path) {
if (!isPathPartPortable(part.toString())) {
return false;
}
}
return true;
}
public static boolean isPathPartPortable(String name) {
return !RESERVED_WINDOWS_FILENAMES.matcher(name).matches();
}
public static String getFullResourcePath(String filename) {
return FilenameUtils.getFullPath(filename).replace(File.separator, "/");
}
public static String normalizeResourcePath(String filename) {
return FilenameUtils.normalize(filename).replace(File.separator, "/");
}
public static DataResult<List<String>> decomposePath(String path) {
int segmentEnd = path.indexOf(47);
if (segmentEnd == -1) {
return switch (path) {
case "", ".", ".." -> DataResult.error(() -> "Invalid path '" + path + "'");
default -> !containsAllowedCharactersOnly(path) ? DataResult.error(() -> "Invalid path '" + path + "'") : DataResult.success(List.of(path));
};
} else {
List<String> result = new ArrayList<>();
int segmentStart = 0;
boolean lastSegment = false;
while (true) {
String segment = path.substring(segmentStart, segmentEnd);
switch (segment) {
case "":
case ".":
case "..":
return DataResult.error(() -> "Invalid segment '" + segment + "' in path '" + path + "'");
}
if (!containsAllowedCharactersOnly(segment)) {
return DataResult.error(() -> "Invalid segment '" + segment + "' in path '" + path + "'");
}
result.add(segment);
if (lastSegment) {
return DataResult.success(result);
}
segmentStart = segmentEnd + 1;
segmentEnd = path.indexOf(47, segmentStart);
if (segmentEnd == -1) {
segmentEnd = path.length();
lastSegment = true;
}
}
}
}
public static Path resolvePath(Path root, List<String> segments) {
int size = segments.size();
return switch (size) {
case 0 -> root;
case 1 -> root.resolve(segments.get(0));
default -> {
String[] rest = new String[size - 1];
for (int i = 1; i < size; i++) {
rest[i - 1] = segments.get(i);
}
yield root.resolve(root.getFileSystem().getPath(segments.get(0), rest));
}
};
}
private static boolean containsAllowedCharactersOnly(String segment) {
return STRICT_PATH_SEGMENT_CHECK.matcher(segment).matches();
}
public static boolean isValidPathSegment(String segment) {
return !segment.equals("..") && !segment.equals(".") && containsAllowedCharactersOnly(segment);
}
public static void validatePath(String... path) {
if (path.length == 0) {
throw new IllegalArgumentException("Path must have at least one element");
} else {
for (String segment : path) {
if (!isValidPathSegment(segment)) {
throw new IllegalArgumentException("Illegal segment " + segment + " in path " + Arrays.toString((Object[])path));
}
}
}
}
public static void createDirectoriesSafe(Path dir) throws IOException {
Files.createDirectories(Files.exists(dir) ? dir.toRealPath() : dir);
}
static boolean isEmptyPath(Path path) {
return path.getNameCount() == 1 && path.getFileName().toString().isEmpty();
}
}引用的其他类
- TropicalFish
- 引用位置:
字段/方法调用 - 关联成员:
Pattern.compile()
- 引用位置: