Autor | Zpráva | ||
---|---|---|---|
Návštěvník Profil * |
#1 · Zasláno: 30. 1. 2014, 12:58:33
Dá se to nějak udělat, že když v adresáři očekávám velké množství souborů, abych mohl procházet soubory které začínají nějakým číslem a nemusel je procházet všechny? To dočasného adresáře zapisuji soubor s názvem ve formátu unixtimestamp_userid ... a chtěl bych zjistit, jestli v posledních 15 minutách uživatel s id userid již provedl akci, tím že zkontroluju existenci tohoto dočasného souboru. Ale samozřejmě že neznám jeho přesný název díky tomu že neznám přesný čas, jen časový limit.
|
||
juriad Profil |
#2 · Zasláno: 30. 1. 2014, 13:11:20
Krátce: Ne.
Dlouze: Můžeš každý den/hodinu soubory ukládat do jiného adresáře pojenovaného třeba podle společného prefixu (prvních několika znaků názvu souboru). Pak stačí procházet takový adresář - neprocházíš všechny soubory. |
||
Keeehi Profil |
Návštěvník:
Existuje funkce glob. Pak ještě pokud máš pole souborů seřazené, můžeš ho od konce procházet jen dokud ten timestamp nebude větší než now-15 min. |
||
juriad Profil |
#4 · Zasláno: 30. 1. 2014, 13:30:12
Keeehi:
Ale tím řešíš problém na straně PHP. PHP bude muset oddřít všechnu práci funkcí glob, která musí projít názvy všech souborů. Řazení je ještě o logaritmus horší, nehledě na zbytečně spotřebovanou paměť. Problém je v tom, že samotný filesystém ti poskytuje informace o souborech v adresářích v nějakém pořadí, které vůbec nemusí odpovídat pořadí vytváření souborů a už vůbec ne názvům souborů. Jediné správné řešení skutečně řešící problém (které jej jen nepřesouvá) je již na úrovni filesystému: zajistit ukládání souborů do jiných adresářů. |
||
Návštěvník Profil * |
#5 · Zasláno: 30. 1. 2014, 13:42:32 · Upravil/a: Návštěvník
Keeehi:
To co píše juriad - taky jsem si všiml, že to vlastně načítá pole se všemi soubory a to já nepotřebuju. Vlastně potřebuju odstranit staré soubory, a pak zkontrolovat jestli v těch nových není duplicitní soubor (duplicitní obsah od uživatele zpracovávajícího požadavek). Přehodil jsem to na userid_timestamp: IF ($handle = opendir(C::TEMP_PATH)): echo "Directory handle: $handle<br>"; echo "Entries:<br>"; $now = time(); /** Check directory **/ while (false !== ($entry = readdir($handle))): $f = C::TEMP_PATH."/".$entry; $time = filemtime($f); if ($now-$time > 90000 ): // 15 minut staré soubory vymazat unlink($f); else: if ( $f[9].$f[8].$f[7]==$id[9].$id[8].$id[7] AND $f[6].$f[5].$f[4].$f[3].$f[2].$f[1].$f[0]==$id[6].$id[5].$id[4].$id[3].$id[2].$id[1].$id[0] AND $entry<>$file AND filesize($entry)==filesize($file) AND file_get_contents($entry)==file_get_contents($file)) /** TOTO JE POKUS O OPAKOVANÉ ODESLÁNÍ: razítko dočasného souboru tohoto uživatele je v časovém limitu menším než 15 minut a bylo zjištěno, že soubor jiného jména se stejnou velikostí a stejným obsahem již existuje */ $lan->printm(70); endif; endwhile; ENDIF; A říkám si, že logické by bylo kdyby data v adresáři byly ukládány a indexovány podle stáří (od nejstaršího po nejmladší) a podle toho také procházeny. To by bylo vyhovující. Načtení / přeskočení názvů nesouvisejících s id tohoto uživatele se nevyhnu... Nevím jestli v tom nejsou chyby, ale toto třeba opravit na celou cestu: AND filesize($f)==filesize($file) AND file_get_contents($f)==file_get_contents($file)) $file je cesta k souboru který jsem už částečně načetl. Je to soubor obsahují dočasné data. Ale pokud je tu duplicitní soubor, tak to hodí hlášku, že akci nelze provést. |
||
Alphard Profil |
#6 · Zasláno: 30. 1. 2014, 14:07:58
Pro porovnání souborů lze použít md5_file().
Na duplicity porovnáváte jen soubory z posledních 15 minut, to jich je opravdu tolik? Jestli ano, můžete si jejich kontrolní hashe ukládat někam mimo, klidně do databáze a mít tam index. Tím byste částečně mohl realizovat i svoji představu ukládání podle stáří. Na základě dotazu do databáze by se mazaly konkrétní soubory, nemusely by se procházet a načítat o nich údaje. |
||
juriad Profil |
#7 · Zasláno: 30. 1. 2014, 14:13:25
Návštěvník:
Na některých systémech ti může tento způsob selhat: http://stackoverflow.com/questions/1676522/delete-files-while-reading-directory-with-readdir Správně by sis měl ukládat kandidáty ke smazání a smazat je až po zavření adresáře (které ti tam mimochodem chybí). Podmínku na řádku 13 můžeš realizovat pomocí sustringu a ne této šílené concatenace, přece nezáleží jestli název porovnáváš odpředu či odzadu. Porovnávání obsahu vyžaduje spoustu dalších operací s filesystémem a může být poměrně pomalý, pokud je soubor velký. Asi bych také šel cestou databáze a ukládání hashů souborů. Jsou vůbec ty soubory potřeba, nešel by celý jejich obsah ukládat do databáze? |
||
Návštěvník Profil * |
#8 · Zasláno: 30. 1. 2014, 14:20:03
juriad:
id je například 0000000009. Když porovnám první tři bajty odzadu tedy 009 či 900 tak se sníží pravděpodobnost shody a tedy nemusím už dále porovnávat :-) Substr by volalo další funkci a v ní kopírovalo řetězec o délce 10 znaků. Tak myslím že moje řešení je rychlejší. Soubor obsahuje mimojiné text zprávy, takže velikost by měla být cca maximálně 1200, ale v praxy spíš krátká zpráva. Alphard To máte pravdu, že těch souborů tam vlastně moc nebude. Oni se ukládaj jen když uživatel odesílá zprávu se zakázanými slovy. |
||
Časová prodleva: 10 let
|
0