我有一个 Perl 应用程序,它解析 MediaWiki SQL 表并显示来自多个 wiki 页面的数据。我需要能够重新创建绝对图像路径来显示图像,例如:.../f/fc/Herbs.jpg/300px-Herbs.jpg
来自 MediaWiki 手册:
Image_Authorisation:“[图像] 路径可以很容易地从文件名中计算出来,并且......”
路径是如何计算的?
接受的答案不正确:
“Herbs.jpg”的 MD5 和为 fceaa5e7250d5036ad8cede5ce7d32d6。前 2 个字符是“fc”,给出了文件路径 f/fc/,这就是示例中给出的内容。
在 PHP 中,您可以调用以下函数来获取 URL。您可能想查看 php 代码以了解它们如何计算路径。
$url = wfFindFile(Title::makeTitle(NS_IMAGE, $fileName))->getURL();
一种可能的方法是计算文件的 MD5 签名(或数据库中的文件 ID),然后基于此构建/查找路径。
例如,假设我们得到一个像“1ff8a7b5dc7a7d1f0ed65aaa29c04b1e”这样的 MD5 签名
路径可能看起来像“/1f/f”或“/1f/ff/8a”
原因是您不想将所有文件都放在 1 个文件夹中,并且您希望能够将它们“分区”到不同的服务器、SAN 或其他任何地方,以同样分布的方式。
MD5 签名是 16 个“十六进制”字符的字符串。所以我们的“/1f/ff/8a”示例为我们提供了 256*256*256 个文件夹来存储文件。这对任何人来说都应该足够了 :)
更新,由于大众需求:
注意- 我刚刚意识到我们正在专门讨论 MediaWiki 是如何做到的。这不是现在 MediaWiki 做的,而是另一种可以做到的方式。
“MD5 签名”是指做这样的事情(Perl 中的代码示例):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$sig 现在是 32 个字母数字字符长:“1ff8a7b5dc7a7d1f0ed65aaa29c04b1e”
然后建立一个这样的文件夹结构:
my $path = '/usr/local/media';
map { mkdir($path, 0666); $path .= "/$_" } $sig =~ m/^(..)(..)(..)/;
open my $ofh, '>', "$path/$sig"
or die "Cannot open '$path/$sig' for writing: $!";
print $ofh "File contents";
close($ofh);
文件夹结构看起来像
/
usr/
local/
media/
1f/
f8/
a7/
1ff8a7b5dc7a7d1f0ed65aaa29c04b1e
我创建了一个名为reorder.sh的小型 Bash 脚本,它将文件从“图像”内部移动到特定的子文件夹:
#!/bin/bash
cd /opt/mediawiki/mediawiki-cur/images
for i in `find -maxdepth 1 -type f ! -name .htaccess ! -name README ! -name reorder.sh -printf '%f\n'`; do
path1=$(echo -n $i | md5sum | head -c1) &&
path2=$(echo -n $i | md5sum | head -c2) &&
mkdir -p $path1/$path2/ &&
mv $i $path1/$path2/;
done