【文件长度+CRC32+TimeStamp+Counter】
// TODO 如何避免文件重复上传? md5吗? 还是文件的计算可以避免此问题?这个信息存储在tracker服务器中吗?
FastDFS中给我们一个非常好的例子,请参考下面的代码:
// 参考FastDFS的文件名称生成算法
/**
1 byte: store path index
8 bytes: file size
FDFS_FILE_EXT_NAME_MAX_LEN bytes: file ext name, do not include dot (.)
file size bytes: file content
**/
static int storage_upload_file(struct fast_task_info *pTask, bool bAppenderFile)
根据上面分析的结果,我们看到,当上传一个文件的时候,我们会获取到如下的信息
1- 文件的大小(通过协议中包的长度字段可以知道,这样的好处在于服务端实现的时候简单,不用过于担心网络缓冲区的问题)
2- CRC32(也是协议包中传输,以便确定网络传输是否出错)
3- 时间戳(获取服务器的当前时间)
4- 计数器(服务器自己维护)
根据上面的4个数据,组织成base64的编码,然后生成此文件名称。根据此文件名称的唯一性,就不会出现被覆盖的情况。同时,唯一性也使得接下来做md5运算后,得到的HASH值离散性得么保证。得到了MD5的哈希值后,取出最前面的2部分,就可以知道要定位到哪个目录下面去。哈希桶的构造是固定的,即二级00-ff的目录情况。
补充说明Base64编码
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
Base64编码表 码值字符码值字符
码值字符
码值字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /