По рекреационным причинам я написал класс PHP, который классифицирует файлы с тегами, а не иерархически, теги хранятся в самом имени файла в виде + tag1 + tag2 + tagN + MD5.EXTENSION, и поэтому я застрял с пределом символов (255), установленным FS / OS. Вот этот класс:
<?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;
}
}
?>
Я считаю, что эта система хорошо работает для пары небольших тегов, но моя проблема в том, что размер всего имени файла превышает 255 символов. Какой подход я должен использовать, чтобы обойти ограничение имени файла? Я имею в виду разделение тегов на несколько жестких ссылок одного и того же файла, но перестановки могут убить систему.
Есть ли другие способы решения этой проблемы?
EDIT - Некоторые примеры использования:
<code><?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 '
';
/ *
[0] => S: / + azul + branco + nuvem + 4151ae7900f33788d0bba5fc6c29bee3.jpg
* /
echo '
';
print_r($images->Get('azul nuvem'));
echo '
';
/ *
[0] => S: / + dunp + logo + 0cedeb6f66cbfc3974c6b7ad86f4fbd3.jpg
[1] => S: / + dunp + logo + 8b9fcb119246bb6dcac1906ef964d565.jpg
[2] => S: / + geoaki + logo + 5f5174c498ffbfd9ae49975ddfa2f6eb.png
* /
echo '
';
print_r($images->Get('logo'));
echo '
';
/ *
[0] => S: / + dunp + logo + 0cedeb6f66cbfc3974c6b7ad86f4fbd3.jpg
[1] => S: / + dunp + logo + 8b9fcb119246bb6dcac1906ef964d565.jpg
* /
echo '
';
print_r($images->Get('logo dunp'));
echo '
';
/ *
[0] => S: / + geoaki + logo + 5f5174c498ffbfd9ae49975ddfa2f6eb.png
* /
echo '
';
print_r($images->Get('geo* logo'));
echo '
';
?>
РЕДАКТИРОВАТЬ: В связи с несколькими предложениями использовать базу данных без сервера или любой другой тип таблицы поиска (XML, плоские, пары ключ / значение и т. Д.), Я хочу уточнить следующее: хотя этот код написан на PHP, идея состоит в том, чтобы перенести его на Python и сделать из него приложение для настольного компьютера - это не имеет никакого отношения (помимо примера, конечно) к PHP. Кроме того, , если мне нужно использовать какую-то таблицу поиска, я определенно пойду с SQLite 3, но то, что я ищу, - это решение, которое не требует каких-либо других дополнительных "технологий", кроме файловая система (папки, файлы и жесткие ссылки).
Вы можете назвать меня чокнутым, но я пытаюсь достичь двух простых целей: 1) освободить систему от "мусора" (например, кому нравится Thumbs.db или DS_STORE?) И 2) сохранить файлы легко идентифицируется, если по какой-то причине справочная таблица (в данном случае SQLite) становится занятой, поврежденной, потерянной или забытой (например, в резервных копиях).
PS: предполагается, что он будет работать как в Linux, Mac, так и в Windows (под NTFS).