у каждого файла, есть идентификатор - число.
число может быть большим, а пока - это 60k
хочется раскидать не тупо по одноуровневой структуре, когда
Код: Выделить всё
$path = ceil($ID/ 1000) . "/" . $ID . ".bin";
тока вот идей нету

Код: Выделить всё
$path = ceil($ID/ 1000) . "/" . $ID . ".bin";
Код: Выделить всё
mkdir('/tmp/00/00/01',0755,true);
Код: Выделить всё
is_dir('/tmp/00/00/01');
Код: Выделить всё
$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";
Код: Выделить всё
$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);
}
Лучше так: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;
Код: Выделить всё
#$FullFilePath в данном случае будет
# /tmp/00/00/01/00.bin
$BasePath = '/tmp/';
$FileExt = '.bin';
$id=str_replace(array($BasePath,$FileExt,'/'),'',$FullFilePath);
А не быстрее было бы использовать fileinode? И массив склеивать не нужно, а сразу берем скомпилированную функцию и вперед.ita писал(а):2GhOsT_MZ
Согласен, так лучше,и да, виноват,ошибся.
ну и + из такого хранения файлов можно легко получить его изначальный идентификаторкак-то так получаетсяКод: Выделить всё
#$FullFilePath в данном случае будет # /tmp/00/00/01/00.bin $BasePath = '/tmp/'; $FileExt = '.bin'; $id=str_replace(array($BasePath,$FileExt,'/'),'',$FullFilePath);
я предлагал получить не inode файла, а идентификатор из которого изначально формировался путь и имя файлаGhOsT_MZ писал(а):А не быстрее было бы использовать fileinode? И массив склеивать не нужно, а сразу берем скомпилированную функцию и вперед.
вот до этого-то и я сам дошёл...FiL писал(а):я не понял, проблем в чем? разбить число на "двойки"? еденицы-сотни-десятки тысяч-миллионы ?
Так вроде просто.
И будет тебе не более 100 записей в каждом каталоге.Код: Выделить всё
$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";
Код: Выделить всё
$str = '10000000000012321123';
for($i=0;$i<(strlen($str)-2);$i++)
{
$path .= $str[$i];
if($i%2==1)
{
$path .= '/';
}
}
Код: Выделить всё
$str = '10000000000012321123';
$length = strlen( $str ) - 2 ;
for( $i = 0; $i <= $length; $i + 2 )
{
$path .= $str[$i] . $str[$i + 1] . '/';
}
Тогда извиняюсь, тупанул, причем жестко...)я предлагал получить не inode файла, а идентификатор из которого изначально формировался путь и имя файла
а какие проблемы с любым числом и без ухода в строку? Если нет требования, чтоб путь к файлу был одинаковой длины для любого файла, то тоже не проблема.Alex Keda писал(а):устраивает != красиво
а красиво - без уходов в строку, и с любым числом
--
красивого решения, пока не вижу
ну да ладно, как верно замечено - совершенству пределов нет
неполучилось.FiL писал(а):а какие проблемы с любым числом и без ухода в строку? Если нет требования, чтоб путь к файлу был одинаковой длины для любого файла, то тоже не проблема.Alex Keda писал(а):устраивает != красиво
а красиво - без уходов в строку, и с любым числом
--
красивого решения, пока не вижу
ну да ладно, как верно замечено - совершенству пределов нет
делишь на 100 (нацело с остатком) пока не получишь 0 и складываешь остатки в в путь. Для мелких $ID путь будет короче. Для больших - длиннее.
Но в каждом каталоге будет не более 100 файлов и 100 подкаталогов. Если это много (200 записей), то дели не на 100, а на 50
Код: Выделить всё
$path = '.bin';
while ($ID > 0) {
$path = '/' . ($ID % 100) . $path;
$ID = floor($ID / 100);
}
во!FiL писал(а):ну, естественно, потом надо к $path приделать $root какой-то и создать нужные каталоги. Но это таки уже сам.Код: Выделить всё
$path = '.bin'; while ($ID > 0) { $path = '/' . ($ID % 100) . $path; $ID = floor($ID / 100); }
Код: Выделить всё
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);
}