正确地处理文件

拼接文件路径:使用Path,且文件分隔符使用File.pathSeparator,不要硬编码为/或者\

//假设有如下文件:/Users/yue/Desktop/test.ev4
Path path = Paths.get("/Users", "yue", "Desktop", "test.ev4");

//注意,这种方式是错误的,即Path只会从第二个参数开始,自动添加文件分隔符,且第一个参数应该是有效路径
Path path = Paths.get(File.pathSeparator, "Users", "yue", "Desktop", "test.ev4");

读取文件所有内容前,先判断文件大小,防止OOM

public static byte[] readAllBytes(String fileName, long maxSize) throws IOException {
    Path path = Paths.get(fileName);
    long size = Files.size(path);
    if (size > maxSize) {
        throw new IOException("file: " + path + ", size:" + size + "> " + maxSize);
    }
    return Files.readAllBytes(path);
}

public static List<String> readAllLines(String fileName, Charset charset, long maxSize) throws IOException {
    Path path = Paths.get(fileName);
    long size = Files.size(path);
    if (size > maxSize) {
        throw new IOException("file: " + path + ", size:" + size + "> " + maxSize);
    }
    return Files.readAllLines(path, charset);
}

遍历文件:使用FileVisitor

判断文件是否在某路径下:使用file.getCanonicalPath(),不必递归

监视文件改变:使用WatchService

Web服务器防止非法的文件路径访问

字符截断攻击和文件历遍漏洞原理:在文件名中插入%00的URL编码,web服务器会把%00后面的内容抛弃。

例如这样的URL:http://www.test.com/../../../../etc/passwd.gif

防范方法

  • 写入文件前,判断文件是否在父路径下,参考上面的函数。

  • 利用Java的安全机制

参考

在Java里处理文件的技巧:大部分内容来源于此,略有修正和补充

Check if file is in (sub)directory

Last updated