How to Check For File Lock

How to check for file lock?

No, unfortunately, and if you think about it, that information would be worthless anyway since the file could become locked the very next second (read: short timespan).

Why specifically do you need to know if the file is locked anyway? Knowing that might give us some other way of giving you good advice.

If your code would look like this:

if not locked then
open and update file

Then between the two lines, another process could easily lock the file, giving you the same problem you were trying to avoid to begin with: exceptions.

Test if file is locked

if (!flock($fp, LOCK_EX|LOCK_NB, $wouldblock)) {
if ($wouldblock) {
// another process holds the lock
}
else {
// couldn't lock for another reason, e.g. no such file
}
}
else {
// lock obtained
}

As described in the docs, use LOCK_NB to make a non-blocking attempt to obtain the lock, and on failure check the $wouldblock argument to see if something else holds the lock.

How to check in command-line if a given file or directory is locked (used by any process)?

Not sure about locked directories (does Windows have that?)

But detecting if a file is being written to by another process is not difficult.

@echo off
2>nul (
>>test.txt echo off
) && (echo file is not locked) || (echo file is locked)

I use the following test script from another window to place a lock on the file.

(
>&2 pause
) >> test.txt

When I run the 2nd script from one window and then run the 1st script from a second window, I get my "locked" message. Once I press <Enter> in the 1st window, I get the "unlocked" message if I rerun the 1st script.

Explanation

Whenever the output of a command is redirected to a file, the file of course must be opened for write access. The Windows CMD session will attempt to open the file, even if the command does not produce any output.

The >> redirection operator opens the file in append mode.

So >>test.txt echo off will attempt to open the file, it writes nothing to the file (assuming echo is already off), and then it closes the file. The file is not modified in any way.

Most processes lock a file whenever they open a file for write access. (There are OS system calls that allow opening a file for writing in a shared mode, but that is not the default). So if another process already has "test.txt" locked for writing, then the redirection will fail with the following error message sent to stderr - "The process cannot access the file because it is being used by another process.". Also an error code will be generated upon redirection failure. If the command and the redirection succeed, then a success code is returned.

Simply adding 2>nul to the command will not prevent the error message because it redirects the error output for the command, not the redirection. That is why I enclose the command in parentheses and then redirect the error output to nul outside of the parens.

So the error message is effectively hidden, but the error code is still propagated outside of the parens. The standard Windows && and || operators are used to detect whether the command inside the parens was successful or failed. Presumably echo off will never fail, so the only possible reason for failure would be the redirection failed. Most likely it fails because of a locking issue, though technically there could be other reasons for failure.

It is a curious "feature" that Windows does not set the %ERRORLEVEL% dynamic variable to an error upon redirection failure unless the || operator is used. (See File redirection in Windows and %errorlevel%). So the || operator must read the returned error code at some low level, not via the %ERRORLEVEL% variable.

Using these techniques to detect redirection failure can be very useful in a batch context. It can be used to establish locks that allow serialization of multiple events in parallel processes. For example, it can enable multiple processes to safely write to the same log file at the "same" time. How do you have shared log files under Windows?


EDIT

Regarding locked folders. I'm not sure how Windows implements this, perhaps with a lock. But if a process has an active directory involving the folder, then the folder cannot be renamed. That can easily be detected using

2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED

EDIT

I have since learned that (call ) (with a space) is a very fast command without side effects that is guaranteed to succeed with ERRORLEVEL set to 0. And (call) (without a space) is a fast command without side effects that is guaranteed to fail with ERRORLEVEL 1.

So I now use the following to check if a file is locked:

2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)

Python : Check file is locked

You can use os.access for checking your access permission. If access permissions are good, then it has to be the second case.

Powershell: Check if a file is locked

With thanks to David Brabant who posted a link to this solution under the initial question. It appears I can do this by starting off with the following function:

function Test-FileLock {
param (
[parameter(Mandatory=$true)][string]$Path
)

$oFile = New-Object System.IO.FileInfo $Path

if ((Test-Path -Path $Path) -eq $false) {
return $false
}

try {
$oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)

if ($oStream) {
$oStream.Close()
}
return $false
} catch {
# file is locked by a process.
return $true
}
}

Then add a 'wait until' function with a timeout.

Thanks for your help!

Check if a file is locked in Java

Under Windows with Sun's JVM, the FileLocks should work properly, although the JavaDocs leave the reliability rather vague (system dependent).

Nevertheless, if you only have to recognize in your Java program, that some other program is locking the file, you don't have to struggle with FileLocks, but can simply try to write to the file, which will fail if it is locked. You better try this on your actual system, but I see the following behaviour:

File f = new File("some-locked-file.txt");
System.out.println(f.canWrite()); // -> true
new FileOutputStream(f); // -> throws a FileNotFoundException

This is rather odd, but if you don't count platform independence too high and your system shows the same behaviour, you can put this together in a utility function.

With current Java versions, there is unfortunately no way to be informed about file state changes, so if you need to wait until the file can be written, you have to try every now and then to check if the other process has released its lock. I'm not sure, but with Java 7, it might be possible to use the new WatchService to be informed about such changes.

How to check if a file is locked or not?

Very simple, just run fnctl with F_GETLK instead of F_SETLK. That will set the data at your pointer to the current state of the lock, you can look up if it is locked then by accessing the l_type property.

please see: http://linux.die.net/man/2/fcntl for details.



Related Topics



Leave a reply



Submit