Делимся секретами создания сайтов

оргaнизовать запись в файл

у меня такой вопрос, как правильно организовать запись в файл так, что-бы записей в нем было не больше чем 100.
файл будет выглядеть к примеру так:

время1 : UserNick1
время2 : UserNick2
время3 : UserNick3
время4 : UserNick4

тоесть, что при записи если в файле больше 100 строчек удалят первый сколько нужно что-бы было 99, а потом добавлять 100-ю.

Мой вариант:
Может перед записыванием нужно считать содержимое в массив, а потом обработать массив, добавить последнюю запись - новые данные, и этот массив записать поновомув заданный файл.

Ответы: 17 → “оргaнизовать запись в файл”

  1. Влад Магера Ответить

    что то я в этой теме нифига не пойму автор общается с публикой ?
    у тебя такой вопрос
    и сам же отвечает на этот вопрос ?
    тоесть, что при записи если в файле бо…
    или я чтото не так понял ?

  2. Игорь Яценко Ответить

    да, отредактировал первый пост, а только сейчас понял что не совсем нормальный текст написал

  3. Михаил Полянин Ответить

    А зачем тебе это вобще нужно?
    <?php
    $filename = "твой_файл";
    $items = file ($filename);
    if (count ($items) > 99)
    for ($i = 100; $i < count ($items); $i++)
    unset ($items[$i]);
    $items[] = "строка"; // новая строка
    $f = fopen ($filename, "w");
    fwrite ($f, implode ("\n\r", $items);
    fclose ($f)
    ?>

  4. Михаил Полянин Ответить

    А как ещё? больше ничего в голову не пришло

  5. Плиско Вячеслав Ответить

    я бы считывал в массив, а после implode('\n', $content), если строчки не по сотне килобайт.

  6. Игорь Яценко Ответить

    зачем нужно – организовать лог файл, только в лог файле хранить последних 100действий.
    вот думаю как правильно организовать бы это.

  7. Алексей Андреев Ответить

    Если важна скорость и требования к памяти (в друг больше строчек хранить захочется), то лучше выкинуть из алгоритма массивы и лишние условия из цикла.
    Файл log-а нужно проинициировать нужным кол-вом пустых строк.
    Читать файл пока не будет найдена вторая строка, потом начинать писать со второй строки, но в другой файл. Когда весь файл прочитан, дописать новую строку. Затем переименование, с затиранием старого файла. Операция переименования атомарная в журналируемых FS, не должно быть проблем с одновременным чтением файла другим процессом, да и целостность гарантируется при сбоях в момент записи.
    Использовать функции fread, fwrite и временный буфер.

  8. Антон Хлыновский Ответить

    Предлагаю на повестку дня следующее извращение: создаем некое подобие базы, max_amount полей с максимальной длиной строки field_length (сколько заблагорассудится), и проходим их по кругу, затирая новым значением самое старое.

    Минусы: файл лога – бинарный.

    Плюсы: при записи лога все предыдущие значения не считываются, т.е., экономится время и не засоряется память.

    <?php
    define("field_length", "256"); // количество символов в поле
    define("max_amount", "100"); // количество записей. Не более 256
    define("base_filename", "base.db"); // файл лога

    function log_write($str){
    $thread = @fopen (base_filename, "r+");
    if($thread===false){
    $thread = fopen(base_filename, "w");
    fwrite($thread, chr(max_amount-1));
    fclose($thread);
    $thread = @fopen (base_filename, "r+");
    };
    $offset = (ord(fread($thread, 1)) + 1) % max_amount;
    fseek($thread, $offset * field_length + 1);
    fwrite($thread, str_pad($str, field_length, "\x00"), field_length);
    fseek($thread, 0);
    fwrite($thread, chr($offset));
    fclose($thread);
    };

    function log_read(){
    $return_value = array();
    $thread = fopen(base_filename, "r");
    $offset = (ord(fread($thread, 1)) + 1) % max_amount;
    fseek($thread, $offset * field_length + 1);
    while(true) {
    $chunk = rtrim(fread($thread, field_length), "\x00");
    if (feof($thread)) break;
    $return_value[] = $chunk;
    };
    fseek($thread, 1);
    for ($i=0; $i<$offset; $i++){
    $return_value[] = rtrim(fread($thread, field_length), "\x00");
    };
    return $return_value;
    };
    ?>

  9. Михаил Полянин Ответить

    Вот изврат. А зачем вооще всё хранить в одном файле? ИМХО, лучше для каждого дня чтобы свой файл создавался тобишь 'log_',data ('d-m-Y', time ()).'.log'. И удалять те которым уже больше n дней. Или принципиально именно по 100 записей хранить в одном файле?

  10. Антон Хлыновский Ответить

    А я сразу говорил, что изврат :)

  11. Виктор Диденко Ответить

    а что мешает использовать возможности операционной системы? пишешь текущую запись в новый файл, потом сливаешь новый файл со старым, сохраняешь в старое имя, новый файл удаляешь, старый (который уже содержит новую строчку первой) усекаешь до 100 строк.
    не знаю точно какими командами можно сделать, но если man'ы поворошить, думаю найдется что нить :) почти уверен

  12. Михаил Полянин Ответить

    to Виктор yumaa Диденко далеко не всегда разрешено выполнять команды операционной системы…

  13. Axel Foly Ответить

    // при добавлении строк в файл делаешь:
    // $stringsToAdd – массив строк, которые сейчас надо добавить
    define('STRINGS_AMOUNT', 100);

    $fileName = '/path_to_your_log_file';
    $dstStrings = '';
    if (file_exist($fileName) && !is_dir($fileName)) {
    $strings = explode("\n", file_get_contents($fileName));
    if (is_array($strings)) {
    $strings += $stringsToAdd;
    if ($cnt = count($strings)) {
    if ($cnt > STRINGS_AMOUNT) {
    $dstStrings = array_slice($strings, $cnt – STRINGS_AMOUNT);
    $dstStrings = implode("\n", $dstStrings);
    }
    }
    }
    }

    if (!file_put_contents($fileName, $dstStrings))
    {
    echo 'Cannot write to log!';
    }

    отладить, надеюсь, сможешь – я не проверял правильность функционирования )

  14. Виктор Диденко Ответить

    to Михаил SWD Полянин
    да, не всегда. но если можно, то почему бы не пользоваться. пусть автор отпишется.
    а вообще я согласен с вашим #10

  15. Axel Foly Ответить

    to Виктор yumaa Диденко
    мой вариант позволяет реализовать и такую возможность, при этом выполняя функциональные требования #1

  16. Виктор Диденко Ответить

    да дело не в функциональности. просто сам подход "файл -> массив -> файл" мне кажется подходом через ж..у. и вообще, лог, по смыслу, должен быть логом, а не монитором текущей деятельности. как ты по 100 последним ошибкам определишь, что не работало два дня назад в ночь с пятницы на субботу в три часа ночи, если эта ошибка уже давно стерта?

  17. Axel Foly Ответить

    согласен :) но если у заказчика такие требования – ему можно сказать о том, что такой лог малоэффективен, но реализовать можно и так, как он хочет :)

    к тому же, возможно (тут вопрос к Игорь Яценко :) ), что это типа тестового задания, или по учебе ;)
    такие задания любят давать, просто чтобы посмотреть, как человек умеет работать :)

Ответить