Java File Locking in Windows

I am trying to find out whether or not a file has a lock in Windows.    The overall goal is to find new files in a directory so I can process them.  The files are transferred into the directory via FTP.  The problem is that I need the file to be completely transferred before I process it, but I can't find a way to figure out whether it's completed or not.  The ftp logs do not store the right information for me to use it effectively.  I have tried to find out whether the file had a lock or not, or to see if I could open it for writing, and it always allows me to.  Interesting enough, while it is still being transferred, I cannot move the file, whether is explorer or Java-- so I know there is a lock somewhere, but I just can't figure out how to read it in Java!  

How can I read the lock that prevents the file from being moved without actually trying to move the file?

File f = new File("test");
f.canRead();  // Always returns true
f.canWrite(); // Always returns true
f.renameTo(new File("newFileName")); // returns false when the file is being transferred (helpful)

RandomAccessFile raf = new RandomAccessFile("junk.dat", "rw");
FileChannel channel = raf.getChannel();
FileLock lock = channel.lock(); // always succeeds


mjschehlAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TimYatesCommented:
You could try to move the file...  if you can then it isn't locked?

I think in Windows, FileLocks just prevent moving/deleting of the file...

They don't stop other people locking it for reading...

Hmmmm...

Tim

PS:  I don't have a windows machine to try this out...but I'm sure some other expert will :-)
0
mjschehlAuthor Commented:
Tim,

I don't want to move the file, because I have to handle renaming the file back in the case that there is no lock!  I want to know if there is a lock on it so I don't ever really move the file.

I thought about using JNI to read the file lock, but I have not looked into seeing if it is possible.  I really can't say I know exactly how Windows does locking, either.  
0
JakobACommented:
It differs. not so much with which version of windows as with which filesystem its disks have been formatted for
    http://www.ntfs.com/ntfs_vs_fat.htm
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

mjschehlAuthor Commented:
I did not see any information on ntfs vs fat as far as how windows controls locks.  I am working with NTFS, though, so the question becomes:

How do I read the lock that prevents the file from being moved/renamed on NTFS without actually trying to move it?
0
sure99Commented:
I think we can work around the problem.

You need to try the file to move to a temp directory.
If it succedes, you can do your processing from there and then move bcak to original       directory.  ( or You move bcak to original dir and do processing)

If it does not let you move, you know it is locked, and you go to next file.

Thanks,

0
mjschehlAuthor Commented:
sure99,

I know that I could move the file and move it back, that is how I am handling it now.  My question was stated that I am looking for a solution that does not require moving the file.  The solution I am looking  for will most likely read the lock directly.
0
mjschehlAuthor Commented:
I am still looking for a way to check the locking without affecting the system.
0
doronbCommented:
Ask in the Windows section about a WinAPI call that would let detect file-locks, and then use JNI?
0
mjschehlAuthor Commented:

doronb,

I probably should of asked in the WinAPI area and used JNI, but I was looking for a java solution.  I would still like to know how to do this, and I would award the points gladly to a solution using JNI, but I don't want to have to do the work.

micah
0
doronbCommented:
Basically, you're saying, you want someone to look it up in the API documentations and write the proper DLL + JNI wrappers, Java code, test it and post it all in here when its all done and working? :)
0
mjschehlAuthor Commented:
doronb,

I believe you were trying to be aggressive and offensive in your last comment.   I don't know if you need to be that extreme.   Your first comment was basically the same comment that I made earlier to Tim.  Yes, JNI might work.  But the reason I posted this question is to find guidance on an area that I do not want to spend a lot of time researching.

If someone was an expert in "Java File Locking in Windows"  then I would believe that they would tell me quickly what the WinAPI command is and discuss the steps needed for using it in Java.  If that is the solution.

micah
0
doronbCommented:
But that's the point... Java isn't MEANT to have specific Windows API's therefore an Expert in "Java File Locking in Windows" is a very hard thing to find, since if its File Locking in Windows you wanna do, you probably wouldn't do it in Java in the first place.

I'm willing to look things up in Windows API's to lend a hand, but writing a whole solution involving this research and JNI isn't something people usually do here as far as I know.
0
mjschehlAuthor Commented:

I actually would have thought that Java would have provided a way to test file locking, whether it is run under Windows, Linux, or any other OS.  It seems it would be necessary for accessing files in any file system.  Since apparently Java does not provide a way to access that information, I need the help of someone that understands both Java and Windows.

I am a little confused on how to go forward.  I don't know much about JNI, so I would rather have the WinAPI functions already and have you give an example on how to get the locking information out of it.  But I need help finding the correct WinAPI function to get me back the locking information before that can be done.  I do feel that showing both of those are worth more than 400 points, so if you are interested I will up the points to 800.  If you go even beyond that and provide NEAR complete code, I will award you more.  I think I 1200 is the most I will go though.

Let me know if you have any suggestions about how to go forward.

0
doronbCommented:
I'll do my best, and you'll decide as to whether my code/explanations/links or whatever, is worth it, and if so, how much :)
It'll take some time, so I'll keep you posted in here.
0
mjschehlAuthor Commented:
Sounds good.  I promise I will not let your work go unawarded!
0
doronbCommented:
Ok, I looked at WinAPI, there are two functions FileLock and FileLockEx.
However... before delving into the details of using JNI to call these functions, I looked into FileLocks and channels:

      public static void main(String[] args) {
            try {
                  RandomAccessFile x = new RandomAccessFile("C:\\testfile.txt", "rw");
                  FileLock flx = x.getChannel().lock();
                  System.out.println(flx);
                  x.skipBytes((int)x.length());
                  x.write("Hello...".getBytes());
                  RandomAccessFile y = new RandomAccessFile("C:\\testfile.txt", "rw");
                  // FileLock fly = y.getChannel().lock(); // This would cause the program to deadlock itself because lock(); is blocking!!
                  FileLock fly = y.getChannel().tryLock(); // This doesn't block and deadlocks the program, but the FileLock is NULL!
                  System.out.println(fly);
                  y.write("Byebye...".getBytes());
                  x.close();
                  y.close();
            } catch (IOException ex) {
                  ex.printStackTrace();
            }
      }

this example works as expected, are you sure your code, using the lock() method doesn't block until the file is completely there?

I don't see how Java can "claim" to have FileLocks without using FileLock or FileLockEx on Windows, so I'm not sure that even using JNI and actually calling the WinAPI functions directly would help you in this case since the problem may even be in how the FTP client you're using is updating the files as it downloads them?

Another thing you could think of is simply monitoring the file-size's and when they stop growing, you know they're completely there.

Still working at it though, so I'll keep you posted :)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
doronbCommented:
I've also tried this code:

      public static void main(String[] args) {
            try {
                  RandomAccessFile x = new RandomAccessFile("C:\\test.doc", "rw");
                  FileChannel fc = x.getChannel();
                  FileLock flx = fc.tryLock();
                  while (flx == null) {
                        Thread.sleep(10);
                        flx = fc.tryLock();
                  }
                  x.close();
            } catch (Exception ex) {
                  ex.printStackTrace();
            }
      }

while test.doc was opened by Microsoft Word... the Java program actually waits in the while(...) loop until I close the file from MS-Word!

Can you try that and tell me what happened?
0
mjschehlAuthor Commented:
I will try the test again, but I remember trying and it would not deadlock.  It would return immediately.  However, I do not remember if I actually got a lock back when I ran it.  I will run the tests again hopefully tomorrow, maybe wednesday.  I have a deadline due today.

Thanks,
Micah
0
doronbCommented:
Ok, I hope this works out cause doing anything with JNI isn't a simple thing.
0
mjschehlAuthor Commented:
I am very sorry I have not been more active on this.  It was as I remembered, the file being received by ssh.com sftp server does not stall your program.   To verify, I opened the file with word, and it does stall your program.  In both cases, though, I cannot move the file.

Since I was so slow and you have been so patient, I am awarding you the 800 points.   Since you won't have a good test bed unless you have ssh.com sftp server, it seems like it may be difficult for you to find a solution.  It would be nice to have a little more closure on this subject, so it would be appreciated if you could find out how it may be done using Win32 API-- but that is up to you decide, and anybody who reads this with the same problem could pony up some points in the Win32 area.

Thanks a lot doronb,
Micah
0
mjschehlAuthor Commented:
doronb,

I apologize, I meant to give you 600 points, but I apparently didn't do it right, and there is no forgiveness with this system.  Is there any wany to add 200 points?

Micah
0
doronbCommented:
You can always open a "dummy" question for which you will accept only my comment as an answer and award points for, however, seeing as I'm not sure that a satisfactory soloution can be found (I think that the File-locking API in Window JVM's actually ARE using the WinAPI for file-locks already!) I'm not sure I deserve those points anyway.

Good luck,
Doron
0
kerznerCommented:
Dear doronb:

Even though your answer did not help the one who asked, it turned out to be a perfect solution for my problem, which is purely watching from Java for the user editing file in Word.

You have answered my questions before, so here too, can I open another question, you will answer, and I will accept? It will be good for you and good for future users.
0
doronbCommented:
You can start a new question of course, but asking questions on top of other questions is not allowed.
0
kerznerCommented:
I know. I am asking another question, where this is the answer.

Question then: how to watch for file being edited by a user.

public static void main(String[] args) {
          try {
               RandomAccessFile x = new RandomAccessFile("C:\\test.doc", "rw");
               FileChannel fc = x.getChannel();
               FileLock flx = fc.tryLock();
               while (flx == null) {
                    Thread.sleep(10);
                    flx = fc.tryLock();
               }
               x.close();
          } catch (Exception ex) {
               ex.printStackTrace();
          }
     }
0
doronbCommented:
If you are going to ask a question, you must open a new question and then ask.

You should not attach your question to another question either open or closed!

Read the following link for an explanation: http://www.experts-exchange.com/Community_Support/help.jsp#hi107
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.