Intereting Posts
Как я могу вернуть объект array / json, содержащий объекты json, через вызов ajax php? Объект PHP Array stdClass – значение эха Как заблокировать одноразовые адреса электронной почты в регистрационной форме вашего сайта? Преобразование массивов в другой формат (PHP) MySQL Связанные подзапросы Отправить данные через сообщение Android на PHP php: regex удалить скобку в строке Получить видео длительность файла, размещенного на Amazon S3 Как использовать preg_replace, чтобы добавить один час к значению времени? Как вызвать родительскую функцию из экземпляра дочернего элемента? Мне нужен более эффективный способ проверки наличия нескольких параметров $ _POST isset facebook Uncaught OAuthException: токен активного доступа должен использоваться для запроса информации о текущем пользователе Запрос JavaScript Ajax vs jQuery $ .ajax PHP regex templating – найти все вхождения {{var}} Какая настройка вызывает чувствительные к регистру require_once пути?

PHP, что является лучшим способом записи данных в середине файла без перезаписи файла

Я работаю с большими текстовыми файлами в php (1GB +), я использую

file_get_contents("file.txt", NULL, NULL, 100000000,100); 

Чтобы получить данные из середины файла, но если бы я хотел изменить данные в файле на то, что отличается от исходных данных, мне пришлось бы перезаписать весь файл.

Как я могу изменить данные в файле (переменная длина) без перезаписи данных, если данные больше оригинала? Я сохраняю индекс различных блоков данных в файле и их байтов. Кажется, что единственная альтернатива заключается в том, чтобы выделить x количество байтов для каждой части данных, а затем переписать этот блок, если я захочу его изменить … проблема заключается в том, что для этого потребуется намного больше места, чем нужно нулевые байты, и это займет больше времени для записи … и это все равно не решит, как «удалить» данные, так как файл никогда не может уменьшаться по размеру … Мне действительно нужна помощь здесь …

Если бы я использовал префиксные блоки для каждой части данных в файле, например, 1 мб, тогда мне захотелось ввести данные, которые были всего 100kb , эта запись займет 10-кратное фактическое необходимое пространство, и запись никогда не может быть изменена на что-то большее, чем 1 МБ данных, поскольку он переписывал бы больше, чем 1-й выделенный блок … удаление было бы невозможно … надеюсь, что это имеет смысл … Я не ищу альтернативы, я ищу, чтобы писать и изменять данные в середине файлов, хе-хе …

UPDATE: Да, я бы хотел заменить старые данные, но если новые данные будут больше, чем старые данные, я бы хотел, чтобы остальные данные были добавлены далее в файл …

рассмотрим это: 0000000HELLODATA00000000 нули представляют пустое пространство, ничего … теперь я хотел бы заменить HELLO SOMETHING, теперь, когда что-то больше, чем привет, просто запись в стартовой точке приветствия будет расширяться по-приветствующе и начнет перезаписывать данные. поэтому я бы хотел, чтобы DATA вставлялся в файл, чтобы освободить место для ЧТО-ТО, не переписывая DATA … hehe

Чтобы перезаписать данные:

 $fp = fopen("file.txt", "rw+"); fseek($fp, 100000000); // move to the position fwrite($fp, $string, 100); // Overwrite the data in this position fclose($fp); 

Ввод данных

Это сложно, потому что вам нужно rewrite файл. Его можно оптимизировать с partial modification от point of injection а не от всего файла

 $string = "###INJECT THIS DATA ##### \n"; injectData("file.txt", $string, 100000000); 

Используемая функция

 function injectData($file, $data, $position) { $fpFile = fopen($file, "rw+"); $fpTemp = fopen('php://temp', "rw+"); $len = stream_copy_to_stream($fpFile, $fpTemp); // make a copy fseek($fpFile, $position); // move to the position fseek($fpTemp, $position); // move to the position fwrite($fpFile, $data); // Add the data stream_copy_to_stream($fpTemp, $fpFile); // @Jack fclose($fpFile); // close file fclose($fpTemp); // close tmp } 

Другой вариант функции injectData() :

 function injectData($file, $data, $position) { $temp = fopen('php://temp', "rw+"); $fd = fopen($file, 'r+b'); fseek($fd, $position); stream_copy_to_stream($fd, $temp); // copy end fseek($fd, $position); // seek back fwrite($fd, $data); // write data rewind($temp); stream_copy_to_stream($temp, $fd); // stich end on again fclose($temp); fclose($fd); } 

Он копирует конец файла (начиная с $position onward) во временный файл, ищет назад для записи данных и строчки все обратно.

Вариант ответа Бабы, не уверен, что было бы более эффективно при работе с большими файлами:

 function injectData($file, $data, $position) { $fpFile = fopen($file, "rw+"); $fpTemp = fopen('php://temp', "rw+"); stream_copy_to_stream($fpFile, $fpTemp, $position); fwrite($fpTemp, $data); stream_copy_to_stream($fpFile, $fpTemp, -1, $position); rewind($fpFile); rewind($fpTemp); stream_copy_to_stream($fpTemp, $fpFile); fclose($fpFile); fclose($fpTemp); } injectData('testFile.txt', 'JKL', 3); 

Вариант моего более раннего метода, который устраняет один из вызовов stream_copy_to_stream (), должен быть более темным:

 function injectData3($file, $data, $position) { $fpFile = fopen($file, "rw+"); $fpTemp = fopen('php://temp', "rw+"); stream_copy_to_stream($fpFile, $fpTemp, -1, $position); fseek($fpFile, $position); fwrite($fpFile, $data); rewind($fpTemp); stream_copy_to_stream($fpTemp, $fpFile); fclose($fpFile); fclose($fpTemp); }