How to check whether a file was locked?

How does java know whether a file is locked by other program?
[68 byte] By [youhaodiyia] at [2007-11-27 9:22:21]
# 1
Your question is poorly worded. There wouldn't be much point in locking a file if nobody could tell.If you're asking how you can tell in Java code, as per your subject line, the answer is to try to lock the file yourself.
ejpa at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 2
Why?Because I have two programs share one file. One program write the file, the other read from the file. When the program to write the file, it will lock it. If the other program want to read the file, it will check wether the file is locked.
youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 3
I agree. Your question?
ejpa at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 4
So i need the program konw whether the other program has locked the file.
youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 5
You try to lock the file in the reading program, as I told you 3 hours:45 minutes ago.Lock it read-only.
ejpa at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 6

No, I need to know wether any other program has locked the file. For example, I need a method like this:

public boolean isLocked(String filename){

// return true if another program has locked this file

// return false if no other program locked this file

}

youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 7
Read the API.There is no way to do what you want. The closest you can get is thetryLock methods. However if the file is not already locked then this aquires the lock.matfud
matfuda at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 8
Can I lock a file only for reading or writing? For example, I locked a file by reading permission which means other programs can't read the file but can write the file.
youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 9

You can lock files for read or write or both. What these mean is platform dependent.

Normally if you lock a file for read then other processes can also read it but none can write it.

If you lock a file for write then no other process can access it.

However on many OS's file locks are advisory meaning other processes can still read them i they want to (they can ignore the lock).

On some OS's only one process can read/write from a locked file (implying that there is no difference between read and write locks on these OS's)

matfud

matfuda at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 10

> No, I need to know wether any other program has locked the file.

Yes, and you have to try to lock the file to find that out, as you were already told. And you have to retain that lock for the duration of your reads: otherwise you are permitting the writing program to come along a nanosecond later and start writing to the file. Surely that's not what you want?

What you need to do now is have a good look at http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/FileLock.html

ejpa at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 11

I locked a file for reading, see below:

FileInputStream input = new FileInputStream("test.txt");

ChannelFile channel = input.getChannel();

FileLock lock = channel.tryLock();

the method tryLock() will throw an exception:

java.nio.channels.NonWritableChannelException

at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:818)

at java.nio.channels.FileChannel.tryLock(FileChannel.java:967)

at filelocking.LockFile.main(LockFile.java:20)

I read the api doc, NonWritableChannelException will be thrown if the channel is not opened for writing. How can i make the channel open for writing?

youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 12
by opening a writable channel...
jwentinga at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 13
You're going in the wrong direction. You don't want a writable channel: you don't want an exclusive lock. You want a shared-read lock. See http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/FileChannel.html#tryLock(long,%20long,%20boolean)
ejpa at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 14
How can i open a writable channel?
youhaodiyia at 2007-7-12 22:16:45 > top of Java-index,Java Essentials,Java Programming...
# 15

There is a bug open against the doumentation of FileChannel

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4510562

Either you ask for a shared lock on a read only channel or you ask for an exclusive lock but MUST have write access (or read/write access)

I'm not sure what happens if you ask for a shared lock on a read only file when the OS does not support shared locks. On these OS's the shared lock is converted to an exclusive lock so you would probably have the same problem.

The safest bet is to try to obtain a shared lock on a read only file. If it fails then open a read/write RandomAccessFile and lock that exclusively. Then open a read only FileInputStream on the same file.

This means that potentially you might be able to get performance optimizations from shared access but you fall back to excluive access.

(Note that locks do not work inside java. They only work (may work) between the java process and other processes running on the OS.)

matfud

matfuda at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 16
There are tryLock () and lock () method in FileChannel class. And isShared() method in FileLock class returns whether a lock is shared. But how can I deside whether get a shared lock or a exclusive lock? Can you give me a simple example?
youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 17
See reply #13 which according to reply #14 you have completely ignored.
ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 18
Yes but it didn't say how to get a shared lock or exclusive lock. for example, I want a method like this:tryLock(int flags)The parameter may be LOCK_SH or LOCK_EX indicating a shared lock or a clusive lock respectively.
youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 19
> I want a method like this:I know you do, and that's what I pointed you to. How hard did you look?
ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 20
According to the FileChannel description, I can get a lock. But whether the lock is shared or exclusive is desided by JVM. Is it correct?
youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 21
Of course. Strange question. The Javadoc should be your primary reference, not these forums. You've already wasted a day by getting that back to front.
ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 22
But I couldn't find the answer from Java Doc
youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 23

Clearly you just need to look harder. After your original question, to which the answer was 'try to lock it', every question you've asked so far is answered in the Javadoc you were referred to.

Unless you want the answer to 'is it [the Javadoc] correct?'. Do you have any reason to disbelieve it?

ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 24

I used the following code to lock a file. There are two programs, one is that when the program is running, the content of "file.txt" will be erased. Second during the 10 seconds, I can use other text editor to modify the file. The program is running in linux environment.

FileOutputStream output = new FileOutputStream("file.txt");

FileChannel channel = output.getChannel();

FileLock lock = channel.tryLock();

System.out.println(lock);

Thread.sleep(10000);

if(lock == null){

System.out.println("Can't get a lock(file.txt)");

}

lock.release();

youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 25

Blimey. You can lead a programmer to the Javadoc but you can't make him read it. You still haven't found the other form of FileChannel.tryLock(), have you? So what you have here is a write lock, not a possible shared-read lock.

I can only assume that the other program isn't getting a write lock on the file either.

ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 26

I know there is a tryLock with three parameters. tryLock() is equal to tryLock(0, Long.MAX_VALUE, false). I need my program lock a file to prevent other programs from modifying it. So i need a write lock. I am wandering why it deletes the content of the file it has locked. In addition, I can't control how the other programs work. They can lock the file or not.

youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 27

> I need my program lock a file to prevent

> other programs from modifying it. So i need a write

> lock.

No you don't, you need a shared-read lock, as you were told yesterday. A shared-read lock excludes file locks. As it says in the Javadoc for FileLock, paragraph 4. If the platform promotes it to a write-lock, fine, but you should try for a shared-read lock if possible if you are only reading.

You really must get around to reading the Javadoc some time.

> I am wandering why it deletes the content of

> the file it has locked.

It doesn't. You did. You created an output file instead of an input file, by creating a writable channel, which you shoudn't do. As I pointed out above. Yesterday.

> In addition, I can't control how the other programs work. They can lock

> the file or not.

In that case you are SOL, you can lock the file all you like, but if the other program isn't trying to lock too, the entire thread is irrelevant.

But in that case why does your subject line read 'How to check whether a file was locked?'

We can only answer the question you ask.

ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 28

If i get a lock on a output file by exclusive lock, it will delete the file. For example:

FileOutputStream output = new FileOutputStream("lock/test.txt");

FileChannel channel = output.getChannel();

FileLock lock = channel.tryLock(0,Long.MAX_VALUE, false);

lock.release();

If i get a lock on a output file by a shared lock, it will throw an exception, for example:

FileOutputStream output = new FileOutputStream("lock/test.txt");

FileChannel channel = output.getChannel();

FileLock lock = channel.tryLock(0,Long.MAX_VALUE, true);

lock.release();

So the tryLock method will never work on a output file lock. And the java doc doesn't say this. Why is there a getFileChannel() method in FileOutputStream class?

youhaodiyia at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 29

> If i get a lock on a output file by exclusive lock,

> it will delete the file.

If you create an output file it will delete the file. Nothing to do with the lock.

> For example:

> FileOutputStream output = new FileOutputStream("lock/test.txt");

Hold it right there. At this point the file is already empty.

You've been told several times already that what you want is a readable channel.

> If i get a lock on a output file by a shared lock, it

> will throw an exception

Why would you put a shared lock on an output file? This makes no sense, and I'm glad to hear it throws an exeption. Shared locks are for input files.

> So the tryLock method will never work on a output

> file lock.

Not if you want a shared lock. Good. Glad to hear it.

But why are you still futzing around with locks if the other program(s) don't lock the file?

ejpa at 2007-7-21 22:59:46 > top of Java-index,Java Essentials,Java Programming...
# 30

If I lock a file, why can other program modify the file?

One program is like this:

FileInputStream input = new FileInputStream("test.txt");

FileChannel channel = input.getChannel();

FileLock lock = channel.tryLock(0,Long.MAX_VALUE,true);

Thread.sleep(10000);

The other program is like this:

FileOutputStream output = new FileOutputStream("test.txt");

output.write(99);

output.close();

During the time when the first program sleeping, run the second program, it will modify the file ("test.txt"). My purpose is to prevent this. How can I do that?

youhaodiyia at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...
# 31

Your original question was how to detect whether another program has the file locked. You have your answer to that.

You have now changed your purpose. You now want to know how to stop a program that doesn't lock the file from modifying it while you have it locked. The answer is that you can't. If the other program don't use locking, it can do whatever it likes (although this is somewhat O/S dependent).

You already asked this question at 16:06 yesterday, and you were given most of the answer above at 17:05. Having to repeat every answer two or three times before you get it is becoming pretty tedious. Is it possible for you to pay more attention?

ejpa at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...
# 32

I changed the program to lock a writable lock:

FileOutputStream output = new FileOutputStream(filename);

FileChannel channel = output.getChannel();

FileLock filelock = channel.tryLock(0,Long.MAX_VALUE,false);

if(filelock.isValid()){

Thread.sleep(10000);

}

filelock.release();

The other program is:

FileOutputStream output = new FileOutputStream(filename);

output.write(99);

output.close();

When the two programs run in windows, the other program will throw an exception to indicate another has locked the file and can't modify the file.

When they are running in linux, the other program will modify the file successfully. I know there should be some different between different OS, but I think linux and windows should support exclusive lock , which is what i used.

youhaodiyia at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...
# 33

Bad luck.

The file locking semantics of Unix were settled in about 1984 by a long-defunct organization called /usr/group, a very early precursor to Usenix and Posix. For some reason it was decided that locking and reading and writing would all be independent, and the only way you could detect a lock would be be trying to acquire one yourself, rather than e.g. a write to a segment of a file which was locked by another process causing an error, as in Windows.

This was a massive step backwards, considering the state of the art of OS file and record management systems at the time, and in fact I submitted a paper to them which said so in no uncertain terms, but there you have it.

Complain to Linus Torvald, or Posix.

Nothing will change, any more than it changed in 1984.

ejpa at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...
# 34
Thanks ejp!I really appreciate.
youhaodiyia at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...
# 35

Actually some versions of Unix (non-Posix) have a brain-dead extension called mandatory file locking, which says that if you lock a segment of a file and another rogue process comes along that doesn't care about locks and wants to write to that segment, it is stalled; all your writes will succeed; and the rogue will be suspended until you release the lock, at which point its write will succeed! wiping out all your carefully transactionalized work.

Incredible but true. Obviously the write to a locked segment of the file should fail instantly. For my view of how it should all have worked, which is much in accordance with http://en.wikipedia.org/wiki/Strict_two-phase_locking, see http://www.telekinesis.com.au/wipv3_6/DataLockingInDraftUnixStandard.A21

ejpa at 2007-7-21 22:59:51 > top of Java-index,Java Essentials,Java Programming...