Код (Text): <?php ini_set('max_execution_time', 3600); ini_set('memory_limit', -1); ini_set('upload_max_filesize', -1); $fp = fopen("filenew.txt", "w+"); function generateKey($length = 8){ $chars = '0123456789'; $numChars = strlen($chars); $string = ''; for ($i = 0; $i < $length; $i++) { $string .= substr($chars, rand(1, $numChars) - 1, 1); } return $string; } $text = array(); $countsum = 0; while ($countsum < 1073741824){ do{ $genKey = generateKey(rand(1, 4000)); $genVal = generateKey(rand(1, 4000)); $sum = strlen($genKey) + strlen($genVal); } while ($sum > 4000); $text[$genKey] = $genVal; $countsum += $sum + 2; echo "$countsum<br>"; }; ksort($text); foreach ($text as $key => $val) { fwrite($fp, "$key\t$val\x0A"); } fclose($fp); ?> Изучаю PHP второй день. Нужно получить текстовый файл размером 1 ГБ. Генерируется долго, но в конце выдает файл размером всего около 50 КБ. В чем может быть причина? Пытался найти какие-либо ограничения, но не нашёл. Использовал OpenServer.
1. тебе не нужен ду-вайл внутри вайла потому что в функции генерации у тебя и так есть цикл. Переделай логику. 2. тебе не нужна переменная-буфер - ты можешь сразу писать блоки в файл. Это будет быстро так как у пыха есть буфер записи, который будет накапливать байты перед сбросом в файл. --- Добавлено --- ну и собственно ошибка в логике: ты в ду-вайле что-то там до какого-то лимита делаешь, а потом записываешь один раз но только текущее значение переменных, а не всё что было нажито непосильным трудом ду-вайла.
Точно, потому что мне не надо дописывать что-то в существующий файл. Какая именно переменная-буфер не нужна? Ду-вайл использовал, так как элемент массива не должен превышать 4000 символа, а ключ и значение может быть размером до 4000. Возможно ошибаюсь, но если бы он из-за ду-вайла записывал один раз, то в файле был бы один элемент массива, а так очень часто лимит доходит до 69000 байтов, реже до 110000
$text И? Ты в теле этого ду-вайла генерируешь две строки, каждая из которых у тебя по длине рандомна. И если они у тебя длиннее 4К то ты уходишь на следующий раунд. ЗАЧЕМ? Если у тебя лимит в 4К то ты можешь придумать рандомное число, сделать одну строку равную этому числу, сделать вторую строку равную 4К-минус-это-число. Всё. Без ду-вайла, регистрации и СМС.
Переделал до такого Код (Text): <?php ini_set('max_execution_time', 3600); ini_set('memory_limit', -1); ini_set('upload_max_filesize', -1); $fp = fopen("filenew.txt", "w+"); function generateKey($length = 8){ $chars = '0123456789'; $numChars = strlen($chars); $string = ''; for ($i = 0; $i < $length; $i++) { $string .= substr($chars, rand(1, $numChars) - 1, 1); } return $string; } $text = array(); $countsum = 0; while ($countsum < 1048576){ $genKey = generateKey(rand(1, 4000)); $lenVal = 4000 - strlen($genKey); $genVal = generateKey(rand(1, $lenVal)); $sum = strlen($genKey) + strlen($genVal); $text[$genKey] = $genVal; $countsum += $sum + 2; echo "$countsum<br>"; }; ksort($text); foreach ($text as $key => $val) { fwrite($fp, "$key\t$val\x0A"); } fclose($fp); ?> По идее файл должен получаться размером около 1 мегабайта, а выходит около 320 килобайт, хотя countsum выходит верный. С меньшим количеством все выходит верно
Давай по новой, Миша, всё хуйня объявили значение переменной от 1 до 4К. это будет длина ключа. объявили строку этой длины. это будет ключ. объявили строку длины 4К-минус-значение-длины-ключа. всё разница? ты объявляешь строку и потом получаешь её длину что чуть более накладно чем сразу знать длину строки и заказать себе такую строку. ну и по моей логике вторая строка сразу добивает до 4К а в твоём алгоритме она почему-то рандом от 1 до частного. хотя это может быть и правильно - тебе, как говорится, виднее в этом моменте. ну и ещё раз: откажись от переменной для накопления. сразу пиши в файл.
Спасибо, теперь заработало после того как убрал второй rand. В условии задачи надо, чтобы длина было до 4к, а не ровно, поэтому это было более подходяще. Переменная для накопления это какая, countsum?
Есть менее критические, такие как, формат файла, размер файла, лимит записей. Все это уже указал в коде
Создать файл заданного размера можно например вот так: PHP: <?php // Размер файла в килобайтах const SIZE_KB = 1024 * 10; // 10 мегабайт const FILE_NAME = 'test.log'; // Строка длиной в 1 килобайт $content = implode(array_fill(0, 1024, '0'), ''); // print strlen($content); // 1024B = 1KB for ($i = 0; $i < SIZE_KB; $i++) { file_put_contents(FILE_NAME, $content, FILE_APPEND | LOCK_EX); } Запуск в терминале: Код (Text): $ php test.php $ du -sh test.log 11M test.log