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

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

bvb

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

Miraage

Angular/Laravel
Регистрация
3 Июн 2008
Сообщения
231
Реакции
51
PHP:
file_put_contents($file, $content, FILE_APPEND);

не оно?
 

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
Нет, этого сделать нельзя.

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

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

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

Я бы пересмотрел саму схему хранения данных, например вместо одного файла завел бы два (индекс+данные) и реализовал бы процедуру экспорта из этих двух в один последовательный файл. Тогда у тебя и вставки будут происходить быстро - в начало, в конец, в любое место, и данные можно будет хранить большого объема, и связь с внешним миром не потеряется.
 

saen

Постоялец
Регистрация
6 Авг 2006
Сообщения
756
Реакции
129
PHP:
file_put_contents($file, $content, FILE_APPEND);
не оно?
Это добавление в конец файла. По умолчанию файловый указатель находится в конце файла. Если его переместить вначало и что-либо записать, все что ниже сотрется. Того что написал ТС без чтения сделать нельзя.
 

rex1963

Гуру форума
Регистрация
19 Фев 2007
Сообщения
228
Реакции
51
Это принципиально, чтобы запись проводилась именно в начало файла, или это нужно для последующего вывода последний-первый?
Здесь довольно популярно написано _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";
	

}
 

saen

Постоялец
Регистрация
6 Авг 2006
Сообщения
756
Реакции
129
Это принципиально, чтобы запись проводилась именно в начало файла, или это нужно для последующего вывода последний-первый?
Здесь довольно популярно написано _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";
    

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

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
как минимум быдлокод

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

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

Тупо бинарный файл по три unsigned int на каждую строку (у тебя ведь файл с данными не больше 4Gb?). StringSize и NextIndex можно вообще-то и short взять, в целях экономии. Памяти в PHP меньше жрать не станет, а размер файла с индексом сократится. StringSize можно вообще выкинуть, если у тебя в данных и так есть ограничители (перевод строки, к примеру). Итого оверхед - 6 байт на строку. А скорости прибавится, и рандомный доступ, и чтение-запись, и вообще, хоть в середину теперь свои строки вставляй - весь файл переписывать не надо, только два аппенда и оверрайт этих 6ти байт в индексном файле. Идеально!
 

Miraage

Angular/Laravel
Регистрация
3 Июн 2008
Сообщения
231
Реакции
51
что-то я под порохом написал бреда :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);
}
 

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
Чувак же просил не считывая весь файл, а у тебя file_get_contents.

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

trooll

PHP кодер
Регистрация
22 Дек 2008
Сообщения
482
Реакции
117
bvb --- Э-з-з не вдаваясь в технические подробности, которые ты не осилишь, то что ты хочешь сделать тяжело реализуемо. Имхо **х. лишней гемор.

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

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

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