文件辅助
基本信息
| 属性 |
值 |
| 类 |
com.github.lunatrius.core.util.FileUtils |
| 成员形式 |
全部 public static |
| 引用来源 |
两处方法均标注了来源链接注释(StackOverflow) |
grep -rn "FileUtils" 在 src/main/java/ 下只命中它自己的第 8 行声明,本 mod 内部零调用,是纯粹的公共 API。
人类可读字节数
| 签名 |
public static String humanReadableByteCount(final long bytes) |
实现要点
| 步骤 |
源码 |
| 单位 |
final int unit = 1024; |
| 小于 1024 |
return bytes + " B"; |
| 指数 |
int exp = (int) (Math.log(bytes) / Math.log(unit)); |
| 前缀字符 |
final String pre = "KMGTPE".charAt(exp - 1) + "i"; |
| 格式化 |
String.format("%3.0f %sB", bytes / Math.pow(unit, exp), pre) |
输出对照
bytes |
返回值 |
说明 |
0 |
0 B |
走小于 1024 分支 |
1023 |
1023 B |
走小于 1024 分支 |
1024 |
1 KiB |
exp = 1 → "KMGTPE".charAt(0) + "i" |
1048576 |
1 MiB |
exp = 2 → charAt(1) + "i" |
1073741824 |
1 GiB |
exp = 3 |
1099511627776 |
1 TiB |
exp = 4 |
1125899906842624 |
1 PiB |
exp = 5 |
1152921504606846976 |
1 EiB |
exp = 6 → charAt(5) |
[!NOTE]
前缀带 i 后缀(IEC 风格),但基数用的是 1024 而非 1000;输出格式 %3.0f 会在数字前补空格凑满 3 字符宽度。exp 最大为 6(long 上限),"KMGTPE" 恰好 6 个字符,不会越界。
路径包含检查
| 签名 |
说明 |
public static boolean contains(final File root, final String filename) |
委托 contains(root, new File(root, filename)) |
public static boolean contains(final File root, final File file) |
比较 file.getCanonicalPath().startsWith(root.getCanonicalPath() + File.separator) |
行为细节
| 情况 |
结果 |
file 确实是 root 下的子路径 |
true |
file 就是 root 本身 |
false(因要求以 root + File.separator 开头) |
file 是 root 的兄弟目录且同前缀 |
false(File.separator 边界检查正好拦住 /root2) |
getCanonicalPath() 抛 IOException |
捕获后 Reference.logger.error("", e) 并 return false |
[!IMPORTANT]
用的是 getCanonicalPath() 而非 getAbsolutePath(),因此符号链接会被解析,.. 也会被折叠——这正是防目录穿越(path traversal)需要的语义。
[!WARNING]
catch 块里 Reference.logger.error("", e) 的消息字符串是空字符串,IOException 只作为 throwable 附在日志堆栈里,因此按消息过滤日志时看不到任何线索。
相关条目