Sorun Etiketi'nde "Dosya Sistemi"

14 Cevap php

Bir hiyerarşik şekilde etiketler yerine dosyaları sınıflandırır bir PHP sınıfı yazıldı etkinlikler nedeniyle, etiketler + tag1 tag2 + + + TAGN MD5.EXTENSION şeklinde dosya kendisinde depolanan ve böylece I ile stucked şeyler vardır FS / OS tarafından dayatılan karakter limiti (255). İşte sınıftır:

<?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;
    }
}

?>

Ben bu sistem küçük etiketleri bir çift için iyi çalışır inanıyorum, ancak tüm dosya boyutu 255 karakter aştığında benim sorunum. Dosya limit bypass etmek için ne yaklaşım almalıyım? Ben aynı dosyanın birçok hard linklere bölme etiketleri düşünüyorum, ama permütasyon sistemi öldürmek olabilir.

Bu sorunu çözmek için başka yolları var mı?

EDIT - Some usage examples:

<?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>';

?>

EDIT: Due to the several suggestions to use a serverless database or any other type of lookup table (XML, flat, key/value pairs, etc) I want to clarify the following: although this code is written in PHP, the idea is to port it to Python and make a desktop application out of it - this has noting to do (besides the example of course) with PHP. Furthermore, if I have to Kesinlikle SQLite 3 ile gidersiniz arama tablosunun çeşit kullanımı, ama ne arıyorum dosya sistemi (klasörler, dosyalar dışında başka ek "teknoloji" içeren olmayan bir çözümdür ve hardlinks).

You may call me nuts but I'm trying to accomplish two simple goals here: 1) keep the system "garbage" free (who likes Thumbs.db or DS_STORE for example?) and 2) keep the files easily identifiable if for some reason the lookup table (in this case SQLite) gets busy, corrupt, lost or forgot (in backups for instance).

PS: This is supposed to run on both Linux, Mac, and Windows (under NTFS).

14 Cevap

Eğer o her dosya için bir bağlantı olan her etiketini da kendi dizini vererek içine bakmak olabilir daha sert / yumuşak bağlantıların kullanımı varsa "etiketi." Eğer birden fazla etiket verildiğinde Sonra iki bulunanlar karşılaştırabilirsiniz. Sonra dosyaları tek bir klasörde depolanır ve tabii adına onları benzersiz sahip olabilir.

Ben bu o etiketi bulunan tüm dosyaları listeleme, etiketi adında bir meta dosyası olan farklı olurdu bilmiyorum.

Windows Bir gezinirken Thumbs.db önbellek başparmak dosyası klasörleri oluşturur benzer şekilde, ile ilgili klasörü her biri için etiketleri bir önbellek oluşturmak isteyebilirsiniz.

Böyle bir meta veri dosyası oluşturma dosya adı kısıtlamaya maruz kalmadan birçok farklı dosya sistemleri arasında çalışma avantajına sahiptir.

"Hayır": Sen cevap olduğuna inanıyorum yeterince soruyu daralmış ettik

Bu bozulabilir çünkü etiketleri merkezi kayıt istemiyorum.

O "çöp" çünkü dosya veya verileri tutmak için her dizininde gizli dosyaları istemiyorsanız.

Eğer malzeme taşımak ve muhtemelen dosya sistemi üzerinde "çöp" teşkil ettiği o tarihte gider çünkü muhtemelen, bağlantıları olan dizin veya dizinleri paralel bir dizi istemiyorum.

Sen surely dosyaların kendilerini içeriği etiketleri koymak istemiyorum.

Yani başka bir yerde dizin yapısında dosyanın adını bir kenara etiketleri koyabilirsiniz var?

No (Ya da en azından taşınabilir bir şey yok).

Kesinlikle (kopyalanmış ve her zamanki araçlarını kullanarak hareket ettirildiğinde) Eğer söz büyük işletim sistemlerinin üçü (üzerinde çalışmak olacağını dosyanın adı ya da bir dosya ile kalmak istiyorum gerçek dosya kendisi dışında meta tutmak için hiçbir yerde yoktur Linux, Mac, Win).

Bu yapabileceği bir taşınabilir meta sistemi vardı, ama yok eğer güzel olurdu. Benim izlenimim etiketleme yapmak için en iyi yolu nedir hakkında genel kabul olmasıdır. Yani her sistem farklı ve ticaret-off farklı bir dizi ile yapar.

Ben işletim sistemleri (hiyerarşik dosya sistemlerinde, GUI arayüzleri, vb) önemli fikirlerin çoğu göre, etiketleme kullanarak nispeten yeni bir fikir olduğunu düşünüyorum. Her üç sistem arasında paylaşılan tesislerinin çoğu oldukça eski ve köklü fikirleri vardır.

Yapabileceğiniz en iyi şey, muhtemelen her sistem bunu nasıl yaptığını incelemek ve sonra portably sistemleri arasındaki işlevsellik düşük ortak payda sağlayacak bir kütüphane yazmak olacaktır.

Belki birileri bunu yapar Python için bir kütüphane yazdı?

C.J.

Bir cevap daha bir beyin fırtınası daha.

CJ @ herhangi bir dış meta olmadan ve dosya tanımlayıcı artı 'tag-bulut' senin tagfs olarak 255 bayt kısıtlaması ile, işaret gibi bir sorun olmaya devam etmektedir.

Sembolik bağlantıları güzel. Bunun yerine tek bir dosya içine tüm tagnames ambalaj, biri birkaç dosya üzerinde etiketleri yayılabilir, ya da olabilir - alanı uğruna - sembolik. adımlar:

  1. Belirli bir dosya için bir sağlama ya da karma hesaplamak
  2. bazı biçiminde bir sembolik bağ saklamak, örneğin -tag veya etiket

I understand, that's what you mean by 'garbage', but if you want to store an arbitrary number of arbitrary tags in a fixed length string, you'll hit an information barrier sooner or later. using a database scales better, but storing and retrieving symlinks should be easy to implement. the 'garbage' could be stored in a single metadata repository with a leading 'dot', which is a widely used and established pratice on some operating systems.

iyi şanslar!

Aslında, ben bu programı bir kabuk uygulama inşa, ve Nautilus dosya tarayıcısı ile entegre etmiş ...

Ben yumuşak-link yaklaşım kullanılır:. Adında bir dizin etiketleri tüm "etiketleri" içerdiği, ve etiketleri etiketleri dizinde sadece dizinleri edildi..

Bir dosya "eğlenceli" ile etiketlenmiş ise, o zaman yumuşak bir bağlantı .tags / fun oluşturulan olurdu .. Ancak, bu yöntem etiketleri aramak için iyi değildir.

Sen de arama desteklemek istiyorsanız, ben sqlite kullanıyorum tavsiye ederiz.

şerefe, JRH.

Dosya sistemi veritabanı, bu yüzden bunu kullanmak.

  1. Dosyanız için bir "benzersiz bir isim" ile geldi. Dosya adı olarak uzun uzay arasında benzersiz olduğu gibi, ne olduğu önemli değil. Dosya adı etiketleri ile ilgisi yoktur.

  2. Bir "depo" dizinine dosya adını karma. Bir bazillion dosya (<1000-2000) zorunda olacak değilseniz, tek bir dizindeki tüm dosyaları saklayabilirsiniz. Aksi takdirde, "kova" dizinleri bir demet yapmak ve doğru dizine dosyayı karma. Bu işlem dosya adına göre, belli ki, deterministik değildir.

  3. Dosya üzerinde her etiket için bir "etiket" dizinde aynı isimde bir "boş" dosyayı saklamak ya, sadece bu etiketi dosyaları listeleyen bir "etiket dosyası" var ya. Belirli bir etiketi dosyaların katrilyonlar var düşünüyorsanız Yine, kova için dosyaları karma.

Bir dosyaya etiket eklemek için, sadece uygun etiket dir dosya başvurusu ekleyin. Etiketini silmek için, aynı şey.

Bir dosyayı silmek için, sadece ana deposundan dosyasını kaldırın. Eğer etiket başvuruları yineleme yaptığınızda, o noktada dosyasını kontrol ve tembel girdileri silebilirsiniz. Muhtemelen yine ilginç bir şey için dosyayı isabet için gidiyoruz.

Bir ayna "meta data" dizinini oluşturmak sonra, dosya için gerçek meta verilerini depolamak istiyorum. Bir dosyayı eklediğinizde, aynı düzeni kullanarak, dosya deposu dizine koyun, ve bir "meta veri deposu" dizinde eşleşen meta veri dosyası. Orijinali silerek bir dosya silme ve meta veri bulunuyor.

Sadece basit dosya işlemleri (dizin kovaları karma dışında) hiçbir dosya sistemi maskaralık, hiçbir bağlantıları, niteliklerini, ne varsa.

Bu size dosya başına "sınırsız" etiketi verir, sen Mark I Gözküresi olmanın gerektirdiği sadece aracı ile komut satırından veya dosya gezgini yönetebilirsiniz. (Bunun adı asla değişmez beri) de gerçek dosya kalıcı referanslar olsun.

Darkest parçası bir dosya var etiketleri ne olduğunu bulmak için "etiket bulutu tarama" gerekir olmasıdır. Bir meta veri dosyası ile gitmek isterseniz, o yılında tag listesini (yani etiketleme / untagging işlemleri karmaşık, ama korkunç olur) koruyabilirsiniz.

Işletim sistemi ve dosya sistemi desteği dosya özniteliklerine uzatılmış ise, etiketleri saklamak için kullanabilirsiniz. OS X ve FreeBSD üzerinde, setxattr görmek ve manuel sayfaları getxattr; Linux ve Solaris benzeri tesisleri var. , Windows NTFS genişletilmiş öznitelikleri için destek vardır. Daha fazla bilgi için wikipedia üzerinde "genişletilmiş dosya özniteliklerine" Bkz.

Sen etiketleri dizinleri yerine dosya öğeleri, yani yerine /dir/tag1+tag2+tagN+MD5.EXT yapmak, /dir/tag1/tag2/tagN/MD5.EXT. Gerekir Sen kaçınılması gereken bir şey olarak dizin hiyerarşisi tedavi ederek çeşitli şekillerde ayak kendinizi çekim ediyoruz.

Eğer bu talep üzerine dizin yapısını oluşturmak zor inanıyorum çünkü bu kaçınma yapan ediyorsanız, PHP's mkdir için, üçüncü bir argüman $recursive bakmak gerekir.

Bu PHP hemen hemen her uygulama dağıtımı derlenmiş gibi 'yerli PHP değil,' çünkü SQLite önlemek için seçme, bir sahte ikilem gibi görünüyor. Bunun yerine bir SQL dışı çözüm istiyorsanız, BerkeleyDB size etiketleri listeleri ile herhangi bir etiket dosya ile dosya listesini ilişkilendirmek için kullanabileceğiniz basit bir anahtar-değer deposu sağlar.

Ama SQL çözümü ile gitmek. Bu, hızlı, taşınabilir, ve düşündüğünüzden daha kolay olacaktır.

"Ben dosya limit bypass için ne yaklaşım almalıdır?"

Nasıl etiketlerini destekleyen bir dosya sistemi hakkında? Tagsistant Eğer işletim sistemini belirtmek vermedi.

Pencerelerde sağ> bir dosya özelliklerini tıklayın ve yorum ve diğer verileri ekleyebilirsiniz. Sen (tabii kullanıcı ile ultra kolayca karmaşa IS OK edebilirsiniz HANGİ) etiketleme sistemi için kullanabilirim

soru diğer sistemler Windows dosya özellikleri dışında bu yorumlar ve verileri okuyabilir, nedir?

Eğer xml deneyin neden bir veritabanı kullanmak istemiyorsanız, bu gibi tüm verileri listesi olabilir:

<file>
  <md5>MD5</md5>
  <body>tag5+tag4+tag3</body>
</file>

Kolayca daha fazla başlık ve açıklama gibi ekleyebilirsiniz.

etiketleri bütün mesele etiketleri çoklu kombinasyonlar için hızlı arama yapabiliyor olmaktır. ideal, bir etiket tablo ile bir veritabanına sahip olmak istiyorum {etiket, yol-dosyaya}. Eğer dosya içinde etiketleri tutarak ayarlanmış eğer, sıkıştırma çeşit kullanmanız gerekir. 2-karakter kodu (: tag1, ab: tag2, ac: TAG3 ... aa gibi) her etiket haritalama, etrafında (db veya düz dosya) bir arama tablosu tutun. Bu üç karakter yeterli kullanın değilse ascii yapışmasını, bu, size ~ 10k etiketlerini vermelidir. Şimdi dosya aa.ag.f2.gx.ty.extension gibi bir şey olacak

Unutulmaması gereken başka bir nokta birden etiketleri üzerinde arama yapmak istiyorum çünkü, size dosya içinde etiket kodları sıkı sözcük için emin olmak istiyorum olmasıdır. O, tüm bu kodları içeren dosya adlarını bulacaktır, hangi, etiketleri aa, F3 ve bir kerede yz arama bir "ls .*aa.*f3.*yz.*" yapmak.