Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
成千上万的图片,我应该如何组织目录结构?(linux)_Linux_Directory Structure - Fatal编程技术网

成千上万的图片,我应该如何组织目录结构?(linux)

成千上万的图片,我应该如何组织目录结构?(linux),linux,directory-structure,Linux,Directory Structure,我的Linux服务器由数千名用户上传数千张图片,该服务器由1和1.com托管。我相信他们使用的是CentOS,但我不确定版本。这是一个语言不可知的问题,但是,为了您的参考,我使用的是PHP 我的第一个想法是将它们全部转储到同一个目录中,然而,我记得不久前,一个目录中可以删除的文件或目录数量是有限制的 我的第二个想法是根据用户的电子邮件地址对目录中的文件进行分区,因为这是我使用的用户名,但我不想遇到目录中目录的限制 无论如何,对于来自user@domain.com,我打算这样做: /images/

我的Linux服务器由数千名用户上传数千张图片,该服务器由1和1.com托管。我相信他们使用的是CentOS,但我不确定版本。这是一个语言不可知的问题,但是,为了您的参考,我使用的是PHP

我的第一个想法是将它们全部转储到同一个目录中,然而,我记得不久前,一个目录中可以删除的文件或目录数量是有限制的

我的第二个想法是根据用户的电子邮件地址对目录中的文件进行分区,因为这是我使用的用户名,但我不想遇到目录中目录的限制

无论如何,对于来自user@domain.com,我打算这样做:

/images/domain.com/user/images...
这样做明智吗?如果成千上万的用户说“gmail”,我甚至可以更深入,像这样

/images/domain.com/[first letter of user name]/user/images...
所以mike@gmail.com那将是

/images/domain.com/m/mike/images...
这是一个糟糕的方法吗?其他人在干什么?我不想遇到太多的目录问题也

相关的:


我使用的另一个需求,但可以满足您的需要是使用一个简单的约定

递增1并获取新数字的长度,然后以该数字作为前缀

例如:

假设“a”是使用最后一个id设置的变量

a = 564;
++a;
prefix = length(a);
id = prefix + a; // 3565
然后,您可以使用以下约定为目录使用时间戳:

20092305 (yyyymmdd)
然后你可以像这样分解你的路径:

2009/23/05/3565.jpg
或更多

这很有趣,因为您可以按日期和数字同时保持排序顺序,有时很有用
您仍然可以在更多目录中分解路径

我将执行以下操作:

在每个图像进入时对其进行MD5哈希。 在数据库中写入MD5散列,您可以在其中跟踪这些内容。 将它们存储在一个目录结构中,在该结构中使用MD5哈希十六进制字符串的前几个字节作为目录名。因此,如果散列为'abcdef1234567890',则将其存储为'a/b/abcdef1234567890'。
使用散列还可以合并多次上载的同一图像。

要扩展Joe Beda的方法:

数据库 数据库 数据库 如果您关心按用户、原始文件名、上载日期、EXIF日期拍摄的照片等对文件进行分组或查找,请将此元数据存储在数据库中,并使用适当的查询来选择适当的文件

使用数据库主键(无论是文件散列还是自动递增的数字)在一组固定的目录中查找文件。或者,在每个目录中使用固定的最大文件数N,填充时转到下一个目录,例如,第k张照片应存储在{somepath}/aaaaaa/bbbb.jpg,其中aaaaaa=floork/N,格式为十进制或十六进制,bbbb=modk,N,格式为十进制或十六进制。如果层次结构对您来说太扁平,请使用类似{somepath}/aa/bb/cc/dd/ee.jpg的内容


不要直接向用户公开目录结构。如果他们使用web浏览器通过HTTP访问您的服务器,请为他们提供一个类似www.myserver.com/images/{primary key}的url,并在内容类型标题中对适当的文件类型进行编码。

以下是我不久前为这种情况编写的两个函数。他们已经在一个拥有数千名成员的网站上使用了一年多,每个成员都有很多文件

本质上,这个想法是使用每个成员唯一数据库ID的最后一位数字来计算目录结构,每个人都有一个唯一的目录。使用最后一个数字,而不是第一个数字,可以确保目录的分布更加均匀。每个成员都有一个单独的目录,这意味着维护任务要简单得多,此外,您还可以直观地看到员工的东西在哪里

// checks for member-directories & creates them if required
function member_dirs($user_id) {

    $user_id = sanitize_var($user_id);

    $last_pos = strlen($user_id);
    $dir_1_pos = $last_pos - 1;
    $dir_2_pos = $last_pos - 2;
    $dir_3_pos = $last_pos - 3;

    $dir_1 = substr($user_id, $dir_1_pos, $last_pos);
    $dir_2 = substr($user_id, $dir_2_pos, $last_pos);
    $dir_3 = substr($user_id, $dir_3_pos, $last_pos);

    $user_dir[0] = $GLOBALS['site_path'] . "files/members/" . $dir_1 . "/";
    $user_dir[1] = $user_dir[0] . $dir_2 . "/";
    $user_dir[2] = $user_dir[1] . $dir_3 . "/";
    $user_dir[3] = $user_dir[2] . $user_id . "/";
    $user_dir[4] = $user_dir[3] . "sml/";
    $user_dir[5] = $user_dir[3] . "lrg/";

    foreach ($user_dir as $this_dir) {
        if (!is_dir($this_dir)) { // directory doesn't exist
            if (!mkdir($this_dir, 0777)) { // attempt to make it with read, write, execute permissions
                return false; // bug out if it can't be created
            }
        }
    }

    // if we've got to here all directories exist or have been created so all good
    return true;

}

// accompanying function to above
function make_path_from_id($user_id) {

    $user_id = sanitize_var($user_id);

    $last_pos = strlen($user_id);
    $dir_1_pos = $last_pos - 1;
    $dir_2_pos = $last_pos - 2;
    $dir_3_pos = $last_pos - 3;

    $dir_1 = substr($user_id, $dir_1_pos, $last_pos);
    $dir_2 = substr($user_id, $dir_2_pos, $last_pos);
    $dir_3 = substr($user_id, $dir_3_pos, $last_pos);

    $user_path = "files/members/" . $dir_1 . "/" . $dir_2 . "/" . $dir_3 . "/" . $user_id . "/";
    return $user_path;

}

sanitize_var是一个支持清除输入的函数,它确保输入为数字,$GLOBALS['site_path']是服务器的绝对路径。乔·贝达(Joe Beda)的答案几乎完美,但请注意,MD5已被证明在笔记本电脑上的iirc 2小时内是可碰撞的

也就是说,如果您真的以所描述的方式使用文件的MD5哈希,那么您的服务将很容易受到攻击。这次袭击会是什么样子

黑客不喜欢特定的照片 他确保这是普通的MD5,你使用的是MD5的image+secret\u字符串可以吓跑他 他使用了一种神奇的方法,将一张“使用你的想象力”的照片与他不喜欢的照片碰撞在一起 他像往常一样上传照片 您的服务将用新服务覆盖旧服务,并同时显示两者 有人说:那就不要覆盖它。然后,如果有可能预测有人会上传一些东西,例如,一张在网上流行的图片可能会被上传,那么有可能先用散列代替它。当用户上传一只小猫的照片时,他会很高兴,他会发现它实际上显示为使用你的ima 这里是基尼亚。
我说:使用SHA1,因为它在iirc 127年内被10000台计算机集群证明是可以破解的?

在这个问题上可能已经晚了。但如果它适合您的用例,一个解决方案可能是文件名哈希。这是一种使用文件名创建易于复制的文件路径的方法,同时还可以创建分布良好的目录结构。例如,您可以使用文件名哈希代码的字节作为其路径:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;
这将导致路径为:

/172/029/cat.gif
然后,您可以通过复制算法在目录结构中找到cat.gif

使用十六进制作为目录名与转换int值一样简单:

导致:

/AC/1D/cat.gif

几年前我写了一篇关于这方面的文章,最近我把它改成了媒体。它还有一些详细信息和一些示例代码:。希望这有帮助

我很确定还有另一个更密切相关的问题,但我没有找到它…当然还有一些数据库或文件系统类型的问题。所有图像都将位于web文件夹的根目录下,因此,如果不使用我们的函数检索它们,它们将无法访问它们。但是,如果你让他们访问它们的结构与你存储它们的结构相结合,那么你就无法更改URL。如果您解除耦合,您可以在以后根据需要更改存储结构。您所说的是针对MD5的前映像攻击,该攻击尚未成功,仅针对碰撞攻击:2005年3月1日,Arjen Lenstra,王晓云,Benne de Weger演示了使用不同的公钥和相同的MD5哈希构造两个X.509证书,这显然是一种实际冲突。。。一些评论:1用一个已知的值给你的哈希加盐。2树平衡散列到文件夹结构中。因此,先把散列的五个字符作为一个文件夹,然后再把下五个字符作为一个文件夹,以此类推。这样,在任何给定的文件夹中,你的文件夹都不会超过100000个。以这种方式使用文件夹结构中的整个哈希。@SteveMidgley您能告诉我更多关于树平衡的信息吗?您是如何计算在任何给定文件夹中不会有超过100000个文件夹的?树平衡结构意味着在结构的每个级别上都有相等的部分。余额的大小应基于您的系统在任何给定级别可以处理的元素数量一个文件夹中允许有多少文件夹+文件?vs您的系统可以处理多少层深度的子文件夹对于您的设计来说是合理的?@IstiakTridip-因此您的算法将哈希a拆分为相等的部分,假设4位数字的第一部分将是文件夹,然后下一部分将是子文件夹,重复直到哈希字符串用完。您使用的散列大小将由上述应用程序/系统/操作系统的宽度/深度问题决定。@SteveMidgley 16^5是一百万。。。可能最多会分支3或4个分支。
/AC/1D/cat.gif