Reputation: 11645
Currently I'm doing it like this:
$f = fopen('test', 'w');
fwrite($f, 'Hi');
fclose($f);
But I have a loop that does some expensive stuff (with files), and I'd like to avoid opening and closing the file handle every time I want to overwrite "test"
It should be something like this:
$f = fopen('test', 'w');
$i = 0;
while($ < 50000){
$i++;
foverwrite($f, 'i = ' . $i);
sleep(5); // just a example
}
fclose($f);
Is this possible?
This script runs in the background in CLI mode and I'm reading the test file from the web with ajax like every 2 seconds. Basically I'm trying to display a progress bar lol
Upvotes: 12
Views: 825
Reputation: 3280
To go along with your example, you could implement your foverwrite()
function using frewind()
like this:
function foverwrite($handle,$content)
{
frewind($handle);
return fwrite($handle,$content);
}
This function will return fwrite()
's return value, so it can readily replace fwrite()
where needed. Also, in case of opening the file in append mode (a or a+) it will just append contens, as frewind()
will make no difference.
However, concerning the purpose of your script, which clearly is interprocess communication, you should take a look at more efficient techniques, like shared memory.
Upvotes: 2
Reputation: 1635
You can do it in following ways
$data = [];//initiate the $data variable as empty array
$i = 0;
while($i < 50000){
$data[] = 'i = ' . $i;
$i++;
}
file_put_contents('file.txt', implode("\n", $data));// implode the array
Upvotes: 1
Reputation: 24587
If you're just aiming to keep a file updated so that it can be accessed by AJAX requests, then do you really need to update it 50000 times? A simple way of cutting your overhead would be to update the file less often. Like this, for example:
for ($i=0; $i<50000; $i++) {
// update progress file every 1000 iterations:
if (!($i % 1000)) file_put_contents('./file.txt', "i = $i");
// --- do stuff ---
}
file_put_contents($f, "i = 50000");
Upvotes: 1
Reputation: 39333
You can keep the file and just rewrite over the contents, while then truncating the file if the size changed. This will be faster than overwriting or deleting and rewriting.
$f = fopen('test', 'w');
$i = 0;
while($i < 50000){
$i++;
rewind($f);
$data = 'i = ' . $i;
fwrite($f, $data);
ftruncate($f, strlen($data)); // <---------- Here's the ticket
sleep(5);
}
fclose($f);
Upvotes: 8
Reputation: 3172
You can update the content of a file by rewinding the file pointer, see fseek(). Be careful, once you set file lenght to N by writing N bytes to it, next time, if you rewind and write X < N bytes, the file will remain N bytes long, containing X bytes of new data and N-X bytes of old stuff.
Anyway, don't worry about opening and closing files several times, they will be cached. Or you can open it on a ramdisk partition.
Upvotes: 9