文件上传命名问题

解决重名问题的两种命名方法

md5加密


计算上传文件md5,以这个md5作为文件名称。这种方式出现重名,并且重名的文件是不一样的的几率由md5出现碰撞的几率决定。

使用md5重新命名的方法,有一个好处,就是上传同样的文件,服务器只会保存一份,不会浪费空间。这个方法的缺点也是比较明显的,就是md5名称看起来不是很友好,而且md5如果出现碰撞,就会导致数据丢失。现在md5的碰撞也逐渐被找到。效率还可以,600k的图片,大概20毫秒。足够了。

这种情况千万不要考虑删除文件,因为你永远不知道有多少用户在引用这个文件。

 

package sdibt.fight.util;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.util.Date;

/**
 * 任意数据都会生成128bit的摘要,转成16进制就是32位
 * md5加密
 * @author 111
 *
 */
public class MD5Util {
	/**
	 * byte数组转16进制字符串
	 * @param bytes
	 * @return
	 */
 public static String bytesToHex(byte[] bytes) {  
     StringBuilder stringBuilder = new StringBuilder();
     int h;
     for (byte b : bytes) {
    	 //保持b由byte到int的二进制低8位的一致性,将高24位置0
    	 /**
    	  * 例如:byte-1的源码是100000001 补码是11111111,转int时jvm为了保存十进制的一致性对补码补1;
    	  * int-1的补码是11...111(32个),所以转int后十进制值没变。但是二进制变了,如果直接转16进制是ffffffff,其实应该是ff;
    	  * 所以为了保持二进制低8位的一致性,将高24置0 
    	  */
    	 if(b<0){
			h=b&0xff;
		}else{
			h=b;
		}
    	 /**
    	  * 一个byte=8bit,4bit为1个16进制数,所以一个10进制byte应该转为2个16进制数,不足16的补0
    	  */
    	if(h<16){
    		stringBuilder.append(0);
    	}
    	stringBuilder.append(Integer.toHexString(h));
	}
	 return stringBuilder.toString();
 }
 /**
  * 获得md5加密后的密文
  * @param s 明文
  * @return
  */
 public static String getMD5(String s){
	 try {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		byte[] digest = md5.digest(s.getBytes("utf-8"));
		s = bytesToHex(digest);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	 return s;
 }
 /**
  * 计算文件内容的md5值
  * @param filePath
  * @return
  * @throws Exception
  */
 public static String getBigFileMD5(String filePath) throws Exception{
	 MessageDigest md5 = MessageDigest.getInstance("MD5");
	 FileChannel channel = FileChannel.open(Paths.get(filePath), StandardOpenOption.READ);
	 ByteBuffer buffer = ByteBuffer.allocate(1024);
	 while(channel.read(buffer)!=-1){
		 buffer.flip();
		 md5.update(buffer);
		 buffer.clear();
	 }
	 return bytesToHex(md5.digest());
 }
 public static void main(String[] args) throws Exception {


 }
 
}

以日期方式重命名

因为每个目录下的文件数量是有限制的,而且单个文件夹下的文件不宜过多,会影响检索速度,所以还要细分目录进行存储,通常用年月日来分目录,就是每天上传的文件保存到一个目录。把上面的格式稍微改一下,改成下面的格式:

2012/09/20/  17  21  55 927386 . jpg
年/月/日/    时  分  秒  微秒   后缀

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值