note 30024 modified in function.fopen by danbrown

From: Date: Mon, 08 Jun 2009 23:45:54 +0000
Subject: note 30024 modified in function.fopen by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-156571@lists.php.net to get a copy of this message
To overwrite a file with a new content without deleting it, and without changing the owner or access rights, it's best to not use: <?php $file = fopen($filename, 'r+b); // binary update mode //... ftruncate($file, 0); fwrite($file, $my_stuff); //... fclose($file); ?> but instead the faster one: <?php $file = fopen($filename, 'r+b); // binary update mode //... rewind($file); fwrite($file, $my_stuff); fflush($file); ftruncate($file, ftell($file)); //... fclose($file); ?> The reason is that truncating a file at size 0 forces the OS to deallocate all storage clusters used by the file, before you write your content which will be reallocated on disk. The second code simply overwrites the existing content where it is already located on disk, and truncates any remaining bytes that may exist (if the new content is shorter than the old content). The "r+b" mode allows access for both read and write: the file can be kept opened after reading it and before rewriting the modified content. It's particularly useful for files that are accessed often or have a size larger than a few kilobytes, as it saves lots of system I/O, and also limits the filesystem fragmentation if the updated file is quite large. And this method also works if the file is locked exclusively once opened (but I would rather recommend using another empty file for locking purpose, opened with "a+" access mode, in "/var/lock/yourapp/*" or other fast filesystems where filelocks are easily monitored and where the webserver running PHP is allowed to create and update lock files, and not forgetting to close the lock file after closing the content file). --was-- To overwrite a file with a new content without deleting it, and without changing the owner or access rights, it's best to not use: $file = fopen($filename, 'r+b); // binary update mode ... ftruncate($file, 0); fwrite($file, $my_stuff); ... fclose($file); but instead the faster one: $file = fopen($filename, 'r+b); // binary update mode ... rewind($file); fwrite($file, $my_stuff); fflush($file); ftruncate($file, ftell($file)); ... fclose($file); The reason is that truncating a file at size 0 forces the OS to deallocate all storage clusters used by the file, before you write your content which will be reallocated on disk. The second code simply overwrites the existing content where it is already located on disk, and truncates any remaining bytes that may exist (if the new content is shorter than the old content). The "r+b" mode allows access for both read and write: the file can be kept opened after reading it and before rewriting the modified content. It's particularly useful for files that are accessed often or have a size larger than a few kilobytes, as it saves lots of system I/O, and also limits the filesystem fragmentation if the updated file is quite large. And this method also works if the file is locked exclusively once opened (but I would rather recommend using another empty file for locking purpose, opened with "a+" access mode, in "/var/lock/yourapp/*" or other fast filesystems where filelocks are easily monitored and where the webserver running PHP is allowed to create and update lock files, and not forgetting to close the lock file after closing the content file). http://php.net/manual/en/function.fopen.php

« previous php.notes (#156571) next »