Ali*_*xel 5 php language-agnostic filesystems operating-system file
出于休闲的原因,我写了一个PHP类,用标签而不是分层方式对文件进行分类,标签以+ tag1 + tag2 + tagN + MD5.EXTENSION的形式存储在文件名中,因此我被困在FS/OS强加的字符限制(255).这是班级:
<?php
class TagFS
{
public $FS = null;
function __construct($FS)
{
if (is_dir($FS) === true)
{
$this->FS = $this->Path($FS);
}
}
function Add($path, $tag)
{
if (is_dir($path) === true)
{
$files = array_slice(scandir($path), 2);
foreach ($files as $file)
{
$this->Add($this->Path($path) . $file, $tag);
}
return true;
}
else if (is_file($path) === true)
{
$file = md5_file($path);
if (is_file($this->FS . $file) === false)
{
if (copy($path, $this->FS . $file) === false)
{
return false;
}
}
return $this->Link($this->FS . $file, $this->FS . '+' . $this->Tag($tag) . '+' . $file . '.' . strtolower(pathinfo($path, PATHINFO_EXTENSION)));
}
return false;
}
function Get($tag)
{
return glob($this->FS . '*+' . str_replace('+', '{+,+*+}', $this->Tag($tag)) . '+*', GLOB_BRACE);
}
function Link($source, $destination)
{
if (is_file($source) === true)
{
if (function_exists('link') === true)
{
return link($source, $destination);
}
if (is_file($destination) === false)
{
exec('fsutil hardlink create "' . $destination . '" "' . $source . '"');
if (is_file($destination) === true)
{
return true;
}
}
}
return false;
}
function Path($path)
{
if (file_exists($path) === true)
{
$path = str_replace('\\', '/', realpath($path));
if ((is_dir($path) === true) && ($path[strlen($path) - 1] != '/'))
{
$path .= '/';
}
return $path;
}
return false;
}
function Tag($string)
{
/*
TODO:
Remove (on Windows): . \ / : * ? " < > |
Remove (on *nix): . /
Remove (on TagFS): + * { }
Remove (on TagFS - Possibly!) -
Max Chars (in Windows) 255
Max Char (in *nix) 255
*/
$result = array_filter(array_unique(explode(' ', $string)));
if (empty($result) === false)
{
if (natcasesort($result) === true)
{
return strtolower(implode('+', $result));
}
}
return false;
}
}
?>
Run Code Online (Sandbox Code Playgroud)
我相信这个系统适用于几个小标签,但我的问题是整个文件名的大小超过255个字符.我应该采取什么方法来绕过文件名限制?我正在考虑在同一文件的几个硬链接上拆分标签,但排列可能会杀死系统.
还有其他方法可以解决这个问题吗?
编辑 - 一些用法示例:
<?php
$images = new TagFS('S:');
$images->Add('P:/xampplite/htdocs/tag/geoaki.png', 'geoaki logo');
$images->Add('P:/xampplite/htdocs/tag/cloud.jpg', 'geoaki cloud tag');
$images->Add('P:/xampplite/htdocs/tag/cloud.jpg', 'nuvem azul branco');
$images->Add('P:/xampplite/htdocs/tag/xml-full.gif', 'geoaki auto vin api service xml');
$images->Add('P:/xampplite/htdocs/tag/dunp3d-1.jpg', 'dunp logo');
$images->Add('P:/xampplite/htdocs/tag/d-proposta-04c.jpg', 'dunp logo');
/*
[0] => S:/+api+auto+geoaki+service+vin+xml+29be189cbc98fcb36a44d77acad13e18.gif
[1] => S:/+azul+branco+nuvem+4151ae7900f33788d0bba5fc6c29bee3.jpg
[2] => S:/+cloud+geoaki+tag+4151ae7900f33788d0bba5fc6c29bee3.jpg
[3] => S:/+dunp+logo+0cedeb6f66cbfc3974c6b7ad86f4fbd3.jpg
[4] => S:/+dunp+logo+8b9fcb119246bb6dcac1906ef964d565.jpg
[5] => S:/+geoaki+logo+5f5174c498ffbfd9ae49975ddfa2f6eb.png
*/
echo '<pre>';
print_r($images->Get('*'));
echo '</pre>';
/*
[0] => S:/+azul+branco+nuvem+4151ae7900f33788d0bba5fc6c29bee3.jpg
*/
echo '<pre>';
print_r($images->Get('azul nuvem'));
echo '</pre>';
/*
[0] => S:/+dunp+logo+0cedeb6f66cbfc3974c6b7ad86f4fbd3.jpg
[1] => S:/+dunp+logo+8b9fcb119246bb6dcac1906ef964d565.jpg
[2] => S:/+geoaki+logo+5f5174c498ffbfd9ae49975ddfa2f6eb.png
*/
echo '<pre>';
print_r($images->Get('logo'));
echo '</pre>';
/*
[0] => S:/+dunp+logo+0cedeb6f66cbfc3974c6b7ad86f4fbd3.jpg
[1] => S:/+dunp+logo+8b9fcb119246bb6dcac1906ef964d565.jpg
*/
echo '<pre>';
print_r($images->Get('logo dunp'));
echo '</pre>';
/*
[0] => S:/+geoaki+logo+5f5174c498ffbfd9ae49975ddfa2f6eb.png
*/
echo '<pre>';
print_r($images->Get('geo* logo'));
echo '</pre>';
?>
Run Code Online (Sandbox Code Playgroud)
编辑:由于有几个建议使用无服务器数据库或任何其他类型的查找表(XML,平面,键/值对等)我想澄清以下内容:虽然这段代码是用PHP编写的,但想法是将它移植到Python并从中创建一个桌面应用程序 - 这当然与PHP有关(当然除了示例).此外,如果我必须使用某种查找表,我肯定会使用SQLite 3,但我正在寻找的是一个除文件系统之外不涉及任何其他"技术"的解决方案(文件夹,文件和硬链接).
你可以叫我疯了,但我想在这里完成两个简单的目标:1)保持系统"垃圾"免费(例如谁喜欢Thumbs.db或DS_STORE?)和2)如果由于某种原因保持文件容易识别查找表(在本例中为SQLite)变得繁忙,损坏,丢失或忘记(例如在备份中).
PS:这应该在Linux,Mac和Windows(在NTFS下)运行.
he_*_*eat 16
如果您使用的是硬/软链接,那么您可能会考虑给每个标记它自己的目录,其中每个文件的链接都带有该"标记".然后,当您获得多个标签时,您可以比较两者中找到的标签.然后,这些文件可以存储在一个文件夹中,当然它们在名称上是唯一的.
我不知道这与标签命名的元文件有什么不同,然后列出该标签中存在的所有文件.