Как правильно добавить строку в начало файла?

Статус
В этой теме нельзя размещать новые ответы.

bvb

Мастер
Регистрация
17 Май 2009
Сообщения
189
Реакции
31
Можно ли как-нибудь добавить строку в начало, не считывая содержимое файла? То есть нужна альтернатива этому
Код:
$old_content = file_get_contents($file); 
fwrite($file, $new_content."\n".$old_content);
 
PHP:
file_put_contents($file, $content, FILE_APPEND);

не оно?
 
Нет, этого сделать нельзя.

Для того, чтобы по-быстрому добавить в начало файла на системах типа FAT, надо перенести стартовый кластер в другое место (запись в таблицу размещения файлов и в ее копию) и заполнить этот стартовый кластер своей начальной строкой (вторая запись). Причем строка будет строго по размеру кластера (т.е. от 512 байт до 32Кб в зависимости от того, как отформатировано устройство).

На NTFS можно создавать NTFS Streams, но в данном случае они никак не помогут. На линуксовых ext2 и ext3 все в теории так же, как и для FAT, только ограничение явно в 512 байт. Так что может быть для тебя это будет и выход (будешь дополнять пробелами свою строку, например. Или дописывать в начало ее реальную длину а при считывании отсекать).

Ну и в любом случае, ты ошибся разделом. Подобные манипуляции требуют низкоуровневых обращений к диску и вообще, гемор еще тот.

Я бы пересмотрел саму схему хранения данных, например вместо одного файла завел бы два (индекс+данные) и реализовал бы процедуру экспорта из этих двух в один последовательный файл. Тогда у тебя и вставки будут происходить быстро - в начало, в конец, в любое место, и данные можно будет хранить большого объема, и связь с внешним миром не потеряется.
 
PHP:
file_put_contents($file, $content, FILE_APPEND);
не оно?
Это добавление в конец файла. По умолчанию файловый указатель находится в конце файла. Если его переместить вначало и что-либо записать, все что ниже сотрется. Того что написал ТС без чтения сделать нельзя.
 
Это принципиально, чтобы запись проводилась именно в начало файла, или это нужно для последующего вывода последний-первый?
Здесь довольно популярно написано _http://kurepin.ru/php/zametki/add_str/

Если нужно только для вывода на экран, пиши в конец файла и делай
PHP:
$lines = array_reverse(file('u.txt'));

// Осуществим проход массива и выведем номера строк и их содержимое в виде HTML-кода.
foreach ($lines as $line_num => $line) {
    echo "Строка #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
	

}
 
Это принципиально, чтобы запись проводилась именно в начало файла, или это нужно для последующего вывода последний-первый?
Здесь довольно популярно написано _http://kurepin.ru/php/zametki/add_str/

Если нужно только для вывода на экран, пиши в конец файла и делай
PHP:
$lines = array_reverse(file('u.txt'));

// Осуществим проход массива и выведем номера строк и их содержимое в виде HTML-кода.
foreach ($lines as $line_num => $line) {
    echo "Строка #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
    

}
как минимум быдлокод
 
как минимум быдлокод

Я говорю, индексы тебя спасут!

Filepos:StringSize:NextIndex
Filepos:stringsize:NextIndex
....

Тупо бинарный файл по три unsigned int на каждую строку (у тебя ведь файл с данными не больше 4Gb?). StringSize и NextIndex можно вообще-то и short взять, в целях экономии. Памяти в PHP меньше жрать не станет, а размер файла с индексом сократится. StringSize можно вообще выкинуть, если у тебя в данных и так есть ограничители (перевод строки, к примеру). Итого оверхед - 6 байт на строку. А скорости прибавится, и рандомный доступ, и чтение-запись, и вообще, хоть в середину теперь свои строки вставляй - весь файл переписывать не надо, только два аппенда и оверрайт этих 6ти байт в индексном файле. Идеально!
 
что-то я под порохом написал бреда :D
вот как-то так
PHP:
/**
 * Добавить содержимое в начало файла
 *
 * @param  string  $filename - Файл, куда добавляем
 * @param  string  $content - Содержимое, которое нужно добавить
 * @param  boolean $newline - [Опционально] Добавить разрыв строки?
 * @return integer - Длина записанной строки
 */
function file_put_contents_prepend($filename, $content, $newline = FALSE)
{
    $current = file_get_contents($filename);
    if ($newline === TRUE) $content = "\n" . $content;
    return file_put_contents($filename, $content . $current);
}
 
Чувак же просил не считывая весь файл, а у тебя file_get_contents.

Короче мое резюме - нет, так просто дописать к началу произвольного файла текст не получится. Или придется считывать и перезаписывать весь файл (1), или это будет не произвольный файл (2), или надо очень заморочено переставлять кластеры на низком уровне (3) - и работать это будет с большими ограничениями и только на конкретной файловой системе. Кроме этих трех других вариантов не вижу.
 
bvb --- Э-з-з не вдаваясь в технические подробности, которые ты не осилишь, то что ты хочешь сделать тяжело реализуемо. Имхо **х. лишней гемор.

В свое время тоже как то марочился с этой проблемой дня 2, в итоге забил овчинка выделки не стоит, меняй архитектуру работы с файлами в своих проектах, дешевле будет;)

venetu - красавчик:ay: умеешь вынести мозг, и поднять настроение. Представляю как у ТС все перевернулось в мозгу после прочтение твоего первого и второго поста в топике. ТС Хотел увидеть готовое решение, но получил полную *опу огурцов...:D

Как говориться искореним незнание, непонятными терминами и мат. частью, научим пользоваться поиском, и просто надаем подзатыльников, обращайтесь, не дорого, постоянным клиентам скидки:D
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху