简单的目录分离

问题:

开发web应用的过程中,我们通常会有文件上传的需求,一般由客户端上传到服务器上的文件不会被保存到数据库中(这样会产生一定的安全性问题),而是将上传的文件保存到服务器上的一个特定的目录中.如果单单将所有的文件都保存到一个目录中,也会产生一些问题,当网站访问量很大,上传文件很多时,服务器上保存文件的目录会由于保存太多的文件,而产生打开和读写都很缓慢的问题.解决这个问题的思路就是对上传的文件按照一定的规则,保存到不同的目录中.

解决方案:

思路一:可以按照上传的时间将文件保存到不同的目录中,如2018年1月份上传的文件,保存到 /2018/1 目录中.当然根据网站的流量,这样的目录层次还可以继续划分下去.

代码实现:

/**
 * 目录规则:/yyyy/MM/dd
 * 按时间生成上传文件的存储路径的思路简单,而且一般的web应用使用这种方式也可以满足需求.
 * 如果网站访问量很大,上传文件很多时,还可以继续往下分:/yyyy/MM/dd/hh/mm..
 * */
public static String getPathByTime() {
    StringBuilder path = new StringBuilder();
    // 按系统当前时间计算出存储路径
    Calendar currTime = Calendar.getInstance();
    int year = currTime.get(Calendar.YEAR);
    int month = currTime.get(Calendar.MONTH) + 1;
    int day = currTime.get(Calendar.DAY_OF_MONTH);
    // 字符串拼接
    path.append(File.separator + year).append(File.separator + month).append(File.separator + day);
        
    return path.toString();
}

思路二:目录分离算法,其实就是一个小技巧,使用它可以得到一个目录结构,这个目录结构可以保证每个目录中的文件数量不会太多.

步骤1.给定一个唯一的文件名,获取这个文件名的哈希码值 code.

步骤2.code 值是一个整数,我们将 code 和 0xf 相与,得到一个 int 值作为第一层目录名(思考一下,这个 int 值的范围,就是0-15).

步骤3.然后将 code 值无符号右移4位,得到一个新的 int 值赋予 code,然后将 code 再和 0xf 相与,得到第二层目录名.

因为 Java 中一个整数占4个字节,也就是32位,那么一个整数按照上述规则,最多右移8次就会归0.所以我们可以将上述过程进行8次,得到8级目录,由于每次右移4位,所以每级目录中最多有16个子目录(0-15).好啦,我只能表述到这里啦.直接看看代码吧.

代码实现:

/**
 * 目录分离算法:由此算法可以得到8级目录,每一级目录中最多有16个子目录,所以此算法最大可计算出42.9亿多个存储路径.
 * 由唯一文件名计算出一个存储路径,可以有效避免在一个目录中存储太多的文件.
 * */
public static String getPath(String name) {
    int hash = name.hashCode();
    StringBuilder path = new StringBuilder();
    for (int i=0; i<8; i++) {
        // hash & 0xf 后,得到0-15中的一个整数
        int dir = hash & 0xf;
        // 将 hash 码无符号右移 4 位(一个整数最多右移8次就归0)
        hash = hash >>> 4;
        // 字符串拼接
        path.append(File.separator + dir);
    }
    return path.toString();
}

总结:当然了,这样的目录划分还有很多其它的规则,根据不同的需求,我们可以选择适合自己的方案.至于上述的方案,第一种简单直接,符合人类思维方式,上传的文件组织的很有规律,比较方便整理;第二种则更加符合计算机思维,对于上传量很大,又没有什么必要管理的应用,也是很好的选择.

 

posted on 2018-03-22 20:15  春眠觉晓  阅读(402)  评论(0编辑  收藏  举报