Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read and write to a file while keeping lock

Tags:

file

php

locking

I am making a simple page load counter by storing the current count in a file. This is how I want to do this:

  1. Lock the file (flock)
  2. Read the current count (fread)
  3. Increment it (++)
  4. Write new count (fwrite)
  5. Unlock file/close it (flock/fclose)

Can this be done without losing the lock?

As I understand it, the file can't be written to without losing the lock. The only way I have come up with to tackle this, is to write a character using "r+" mode, and then counting characters.

like image 936
Znarkus Avatar asked Mar 15 '10 22:03

Znarkus


People also ask

How do I lock a document from being edited?

Right-click on the file. In the menu that appears, select Lock File.

What is write lock for a file?

An exclusive or write lock gives a process exclusive access for writing to the specified part of the file. While a write lock is in place, no other process can lock that part of the file. A shared or read lock prohibits any other process from requesting a write lock on the specified part of the file.

What happens when you lock a file?

File locking is a mechanism that restricts access to a computer file, or to a region of a file, by allowing only one user or process to modify or delete it at a specific time and to prevent reading of the file while it's being modified or deleted.


3 Answers

As said, you could use FLock. A simple example would be:

//Open the File Stream
$handle = fopen("file.txt","r+");

//Lock File, error if unable to lock
if(flock($handle, LOCK_EX)) {
    $count = fread($handle, filesize("file.txt"));    //Get Current Hit Count
    $count = $count + 1;    //Increment Hit Count by 1
    ftruncate($handle, 0);    //Truncate the file to 0
    rewind($handle);           //Set write pointer to beginning of file
    fwrite($handle, $count);    //Write the new Hit Count
    flock($handle, LOCK_UN);    //Unlock File
} else {
    echo "Could not Lock File!";
}

//Close Stream
fclose($handle);
like image 158
Jamescun Avatar answered Sep 29 '22 17:09

Jamescun


I believe you can achieve this using flock. Open a pointer to your file, flock it, read the data, write the data, then close (close automatically unlocks).

http://php.net/flock

like image 20
Adam Hopkinson Avatar answered Sep 29 '22 16:09

Adam Hopkinson


Yes, you have to use rewind before ftruncate. Otherwise, the old content of the file is only refilled with zeros.

The working sequence is:

    fopen
    flock LOCK_EX
    fread filesize
    rewind
    ftruncate 0
    fwrite 
    flock LOCK_UN
    fclose
like image 33
Informate.it Avatar answered Sep 29 '22 18:09

Informate.it