PHP, which is the best way to write data in the middle of a file without overwriting the file

I work with large text files in php (1GB +), I use

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

To get data from the middle of the file, but if I wanted to change the data in the file to something that is different from the original data, I would have to overwrite the entire file.

How can I change the data in a file (variable length) without overwriting the data if the data is larger than the original? I save the index of various data blocks in a file and their bytes. It seems that the only alternative is to allocate x number of bytes for each piece of data, and then rewrite this block if I want to change it ... the problem is that this will require a lot more space than zero bytes are needed , and it will take longer to write ... and it still wonโ€™t decide how to โ€œdeleteโ€ the data, since the file will never be reduced in size ... I really need help here ...

If I used prefix blocks for each piece of data in the file, for example 1 mb, then I wanted to enter data that was only 100kb , this record will take 10x the actual required space, and the record can never be changed to anything more than 1 mb of data, since it would rewrite more than the 1st allocated block ... deletion would be impossible ... I hope this makes sense ... I'm not looking for an alternative, I'm looking to write and change the data in the middle of the files heh ...

UPDATE: Yes, I would like to replace the old data, but if the new data is larger than the old data, I would like the rest of the data to be transferred further to the file ...

consider this: 0000000HELLODATA00000000 zeros represent empty space, nothing ... now I would like to replace HELLO SOMETHING, now that something is more than hi, just the entry at the start point of the greeting will expand by greeting and start overwriting the data .. therefore I would like DATA to be placed further in a file to make room for SOMETHING without overwriting DATA ... hehe

+6
source share
3 answers

To overwrite data:

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

Insert data

This is difficult because you must rewrite file. It can be optimized using partial modification from point of injection , and not the whole file

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

Function used

 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 } 
+10
source

Another variant of injectData() function:

 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); } 

It copies the end of the file (from $position forward) to a temporary file, searches back to write data and builds all the backups.

+3
source

Baba's answer option, not sure if it will be more efficient when working with larger files:

 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); 

A variation of my earlier method, which eliminates one of the calls to stream_copy_to_stream (), should be darker:

 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); } 
+2
source

Source: https://habr.com/ru/post/946084/


All Articles