Я работаю с большими текстовыми файлами в 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); }