[PHP] раскидка файлов по директориям

И всё прочее, что касается HTML
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

[PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-11-30 16:28:55

имеем некоторое количество файлов.
у каждого файла, есть идентификатор - число.
число может быть большим, а пока - это 60k

хочется раскидать не тупо по одноуровневой структуре, когда

Код: Выделить всё

$path = ceil($ID/ 1000) . "/" . $ID . ".bin";
а как-то умней... т.е. многуровневую структуру, с числом файлов на директорию около сотни....

тока вот идей нету =))
Убей их всех! Бог потом рассортирует...

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-11-30 17:03:58

а можно предположить сколько файлов будет в итоге?
изменить идентификаторы с 00001 - 60000 на 00000001 - 00060000
структура папок :
000
-00
--00
00.bin
..
99.bin
-01..
путь к файлу получится типа ./000/00/00/01.bin
а алгоритм чтобы так их раскидывать по моему придумать не проблема..

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-11-30 21:13:58

до 10M, думаю (с расчётом на далёкое-далёкое будущее) - но в этом случае сервер ляжет задолго до этого числа =)
--
проблема как раз в алгоритме
Убей их всех! Бог потом рассортирует...

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-01 13:26:20

именование файлов - от 00M до 99M
имя файла - строка, из имени формирутся путь к директории хранения
имена файлов в папках 00-99

Код: Выделить всё

mkdir('/tmp/00/00/01',0755,true);
рекурсивно создаст все необходимые директории

Код: Выделить всё

is_dir('/tmp/00/00/01');
проверит существование директории

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-12-01 23:11:06

нихрена не понял

mkdir я пользоваться умею.
имя как создать и путь к директории?
Убей их всех! Бог потом рассортирует...

FiL
ст. лейтенант
Сообщения: 1374
Зарегистрирован: 2010-02-05 0:21:40

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение FiL » 2011-12-02 1:08:47

я не понял, проблем в чем? разбить число на "двойки"? еденицы-сотни-десятки тысяч-миллионы ?
Так вроде просто.

Код: Выделить всё

$a = floor($ID / 1000000);
$ID = $ID % 1000000;
$b = floor($ID / 10000);
$ID = $ID % 10000;
$c = floor($ID / 100);
$ID = $ID % 100;
$path = $a. "/" . $b . "/" . $c . "/" . $ID . ".bin";
И будет тебе не более 100 записей в каждом каталоге.

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-02 12:34:08

как вариант, превратить число в строку, дополнить нулями если в исходном меньше 8 знаков

Код: Выделить всё

$file = 10;
settype($file;'string');
for($i=0;count($file)<8;$i++)
{
$file .= '0'.$file;
}
дальше создать путь из имени файла, варианты

Код: Выделить всё

$path = substr($file,0,2).'/'.substr($file,2,2).'/'.substr($file,4,2).'/';
#для utf-8 может понадобиться mb_substr, не проверял
#или
$path .= $file[0].$file[1].'/'.$file[2].$file[3].'/'.$file[4].$file[5].'/';


вот рабочий вариант:

Код: Выделить всё

$BasePath = '/tmp/';
$Files = array
(
'00000000',
'00000001',
'00000002',
'10000000',
'10002200',
'10014000',
);
for($i=0;$i<count($Files);$i++)
{
	$Files[$i];
	$FileName = substr($Files[$i],5,2).'.bin';
	$dp = substr($Files[$i],0,6);
	$DirPath = $BasePath.$dp[0].$dp[1].'/'.$dp[2].$dp[3].'/'.$dp[4].$dp[5];
	
	if(!is_dir($DirPath))
	{
	mkdir($DirPath,0755,true);
	}
   #тут можно добавить проверку существования файла и дальше решать что делать если файл существует
	$fr = fopen($DirPath.'/'.$FileName,'w');
	fwrite($fr,'content');
	fclose($fr);
}

GhOsT_MZ
лейтенант
Сообщения: 662
Зарегистрирован: 2011-04-25 11:40:35
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение GhOsT_MZ » 2011-12-02 12:47:15

ita писал(а):как вариант, превратить число в строку, дополнить нулями если в исходном меньше 8 знаков

Код: Выделить всё

$file = 10;
settype($file;'string');
for($i=0;count($file)<8;$i++)
{
$file .= '0'.$file;
}
Лучше так:

Код: Выделить всё

$file = 100;
settype( $file, 'string' );
$file = str_pad( $file, 8 - count( $file ), '0', STR_PAD_LEFT );
Тем более в вашем листинге ошибка, нужно не:

Код: Выделить всё

$file .= '0'.$file;
А:

Код: Выделить всё

$file = '0'.$file;

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-02 12:49:40

2GhOsT_MZ
Согласен, так лучше,и да, виноват,ошибся.

ну и + из такого хранения файлов можно легко получить его изначальный идентификатор

Код: Выделить всё

#$FullFilePath в данном случае будет
# /tmp/00/00/01/00.bin
$BasePath = '/tmp/';
$FileExt = '.bin';
$id=str_replace(array($BasePath,$FileExt,'/'),'',$FullFilePath);
как-то так получается

GhOsT_MZ
лейтенант
Сообщения: 662
Зарегистрирован: 2011-04-25 11:40:35
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение GhOsT_MZ » 2011-12-02 12:52:59

ita писал(а):2GhOsT_MZ
Согласен, так лучше,и да, виноват,ошибся.

ну и + из такого хранения файлов можно легко получить его изначальный идентификатор

Код: Выделить всё

#$FullFilePath в данном случае будет
# /tmp/00/00/01/00.bin
$BasePath = '/tmp/';
$FileExt = '.bin';
$id=str_replace(array($BasePath,$FileExt,'/'),'',$FullFilePath);
как-то так получается
А не быстрее было бы использовать fileinode? И массив склеивать не нужно, а сразу берем скомпилированную функцию и вперед.

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-02 13:14:36

GhOsT_MZ писал(а):А не быстрее было бы использовать fileinode? И массив склеивать не нужно, а сразу берем скомпилированную функцию и вперед.
я предлагал получить не inode файла, а идентификатор из которого изначально формировался путь и имя файла

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-12-02 13:16:07

FiL писал(а):я не понял, проблем в чем? разбить число на "двойки"? еденицы-сотни-десятки тысяч-миллионы ?
Так вроде просто.

Код: Выделить всё

$a = floor($ID / 1000000);
$ID = $ID % 1000000;
$b = floor($ID / 10000);
$ID = $ID % 10000;
$c = floor($ID / 100);
$ID = $ID % 100;
$path = $a. "/" . $b . "/" . $c . "/" . $ID . ".bin";
И будет тебе не более 100 записей в каждом каталоге.
вот до этого-то и я сам дошёл...
я думал естьк акой простой алгоритм ...
а не тупо делить, даже без цикла =)
Убей их всех! Бог потом рассортирует...

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-02 13:34:20

алгоритм, но снова для строки :)

Код: Выделить всё

$str = '10000000000012321123';
for($i=0;$i<(strlen($str)-2);$i++)
{
	$path .= $str[$i];
	if($i%2==1)
	{
		$path .= '/';
	}
}

GhOsT_MZ
лейтенант
Сообщения: 662
Зарегистрирован: 2011-04-25 11:40:35
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение GhOsT_MZ » 2011-12-02 22:06:51

И снова подправлю, если не против)

Код: Выделить всё

$str = '10000000000012321123';
$length = strlen( $str ) - 2 ;
for( $i = 0; $i <= $length; $i + 2 )
{
   $path .= $str[$i] . $str[$i + 1] . '/';
}
Лаконичней, в 2 раза меньше проходов цикла, длина строки считается один раз, а не при каждом проходе цикла, да и помоему нужно <=, а не <, но тут не уверен, ибо голова уже не варит... Кстати да, количество символов должно быть четным, иначе последний символ отбросится (или будет нотайс, что не есть хорошо, но от него спасет isset), хотя изначально была затея сделать именно четное количество символов, как я понял.
я предлагал получить не inode файла, а идентификатор из которого изначально формировался путь и имя файла
Тогда извиняюсь, тупанул, причем жестко...)

ita
ефрейтор
Сообщения: 57
Зарегистрирован: 2006-08-30 12:35:52
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение ita » 2011-12-03 10:19:09

да по моему тут уже нет смысла оптимизировать по двум причинам:
1.TC уже получил вариант, который его устраивает
2. нет предела совершенству :)

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-12-03 22:32:44

устраивает != красиво

а красиво - без уходов в строку, и с любым числом
--
красивого решения, пока не вижу =)
ну да ладно, как верно замечено - совершенству пределов нет
Убей их всех! Бог потом рассортирует...

FiL
ст. лейтенант
Сообщения: 1374
Зарегистрирован: 2010-02-05 0:21:40

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение FiL » 2011-12-04 21:19:40

Alex Keda писал(а):устраивает != красиво

а красиво - без уходов в строку, и с любым числом
--
красивого решения, пока не вижу =)
ну да ладно, как верно замечено - совершенству пределов нет
а какие проблемы с любым числом и без ухода в строку? Если нет требования, чтоб путь к файлу был одинаковой длины для любого файла, то тоже не проблема.
делишь на 100 (нацело с остатком) пока не получишь 0 и складываешь остатки в в путь. Для мелких $ID путь будет короче. Для больших - длиннее.
Но в каждом каталоге будет не более 100 файлов и 100 подкаталогов. Если это много (200 записей), то дели не на 100, а на 50 :)

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-12-04 21:42:18

FiL писал(а):
Alex Keda писал(а):устраивает != красиво

а красиво - без уходов в строку, и с любым числом
--
красивого решения, пока не вижу =)
ну да ладно, как верно замечено - совершенству пределов нет
а какие проблемы с любым числом и без ухода в строку? Если нет требования, чтоб путь к файлу был одинаковой длины для любого файла, то тоже не проблема.
делишь на 100 (нацело с остатком) пока не получишь 0 и складываешь остатки в в путь. Для мелких $ID путь будет короче. Для больших - длиннее.
Но в каждом каталоге будет не более 100 файлов и 100 подкаталогов. Если это много (200 записей), то дели не на 100, а на 50 :)
неполучилось.
запутался в цикле =((
Убей их всех! Бог потом рассортирует...

FiL
ст. лейтенант
Сообщения: 1374
Зарегистрирован: 2010-02-05 0:21:40

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение FiL » 2011-12-04 23:02:33

Код: Выделить всё

$path = '.bin';
while ($ID > 0) {
 $path = '/' . ($ID % 100) . $path;
 $ID = floor($ID / 100);
}
ну, естественно, потом надо к $path приделать $root какой-то и создать нужные каталоги. Но это таки уже сам.

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35454
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: [PHP] раскидка файлов по директориям

Непрочитанное сообщение Alex Keda » 2011-12-05 12:28:28

FiL писал(а):

Код: Выделить всё

$path = '.bin';
while ($ID > 0) {
 $path = '/' . ($ID % 100) . $path;
 $ID = floor($ID / 100);
}
ну, естественно, потом надо к $path приделать $root какой-то и создать нужные каталоги. Но это таки уже сам.
во!
в этих двух стркоах я и запутался...

итог:

Код: Выделить всё

function GetFilePath($Table, $ID){
        # директория файлов
        $DirPath = SPrintF('%s/hosts/%s/files/%s',SYSTEM_PATH,HOST_ID,$Table);
        Debug("[root/system/libs/Upload]: DirPath = " . $DirPath);
        # путь к файлу
        $SubDirPath = '';
        $IDa = $ID;
        while ($IDa > 0) {
                $SubDirPath = '/' . ($IDa % 100) . $SubDirPath;
                $IDa = floor($IDa / 100);
        }
        $FileDirPath = $DirPath . $SubDirPath;
        $FilePath = $FileDirPath . "/" . $ID . ".bin";
        Debug("[root/system/libs/Upload]: FilePath = " . $FilePath);

        return Array('FileDir'=>$FileDirPath, 'FilePath'=>$FilePath);
}
правда, пришлось на живой системе перекладывать файлы с одного пути на другой =))
Убей их всех! Бог потом рассортирует...