0

I have a file I need to read several times from. I have to open the InputStream to the same file in sequence. Now I wonder if that file can be locked for the whole os as long as a specific portion of the Java application is running?

I want to prevent 3 from happening:

  1. Reading file example.txt from myApp.java
  2. Stop Reading file example.txt
  3. Other process writes file (i.e. echo "foo" >> example.txt)
  4. Reading file example.txt from myApp.java

As far as I understand java.nio.FileChannel lock does only lock access to a file for other JVM applications.

xetra11
  • 7,671
  • 14
  • 84
  • 159
  • It is the other way round. The lock is held for the VM. So other processes would get blocked. But multiple threads inside the VM would not. But the actual locking capabilities depend on the underlying file system. See https://docs.oracle.com/javase/8/docs/api/java/nio/channels/FileLock.html for details. – Ralf Mar 11 '20 at 11:58
  • Looks to me like it would be simpler, if appropirate, to ask for an (atomic if the FS supports it) copy of the file. – GPI Mar 11 '20 at 11:58
  • Mandatory locking is supported on Windows, but not well supported on Linux (it exists, but is barely used and usually needs explicit setup to be enabled). I'd aim to work towards an alternative solution to your problem. – Joachim Sauer Mar 11 '20 at 11:59

3 Answers3

1

The Java API for this is java.nio.channels.FileLock. You say:

As far as I understand java.nio.FileChannel lock does only lock access to a file for other JVM applications.

That understanding is incorrect. From the documentation of FileLock:

Platform dependencies

This file-locking API is intended to map directly to the native locking facility of the underlying operating system. Thus the locks held on a file should be visible to all programs that have access to the file, regardless of the language in which those programs are written [emphasis added].

Whether or not a lock actually prevents another program from accessing the content of the locked region is system-dependent and therefore unspecified. The native file-locking facilities of some systems are merely advisory, meaning that programs must cooperatively observe a known locking protocol in order to guarantee data integrity. On other systems native file locks are mandatory, meaning that if one program locks a region of a file then other programs are actually prevented from accessing that region in a way that would violate the lock. On yet other systems, whether native file locks are advisory or mandatory is configurable on a per-file basis. To ensure consistent and correct behavior across platforms, it is strongly recommended that the locks provided by this API be used as if they were advisory locks.

[...]

However, as you can see the exact nature of the lock is platform-specific.

Slaw
  • 37,820
  • 8
  • 53
  • 80
0

Filesystems are OS/implementation specific WRT "locking", and my guess is that to do this reliably you'd have to do it via file permissions.

You do not give any detail about OS/filesystem type, so there's not a specific answer.

If there is a way to "lock" certain files on filesystems, it's not going to be portable, I'll bet.

mikeb
  • 10,578
  • 7
  • 62
  • 120
0

I have an idea to prevent other processes can access to this file is to rename it until your application finished.

1. Load the file and rename it. For example, example.txt to example.txt.tmp
2. Reading file example.txt.tmp from myApp.java
.....
6. Rename your file name back to the original one.
Tran Ho
  • 1,442
  • 9
  • 15
  • Then you'd loose any updates written by other processes. – Ralf Mar 11 '20 at 12:00
  • A clever idea, but it implies that the writes performed by other processes are simply lost / erased in the process. In this acceptable ? – GPI Mar 11 '20 at 12:00
  • @Ralf, The OP said he wants to prevent the updates from other processes, doesn't he? – Tran Ho Mar 11 '20 at 12:01
  • I need to be 100% sure nothing is even writing on the copy – xetra11 Mar 11 '20 at 12:02
  • @TranHo, from my understanding, it's about *Temporarily* preventing *concurrent* access. Not accept writes and erase them as if nothing happened.... – GPI Mar 11 '20 at 12:02
  • @GPI, it can be. xetra11, please confirm it. – Tran Ho Mar 11 '20 at 12:04
  • @GPI, even it's about temporarily preventing concurrent access, I think my solution is still acceptable because this JVM process will hold the file and keep reading it several times. During this period, it doesn't need to be updated from any proceses. However, mine is just a trick which is not really a standard way. :D – Tran Ho Mar 11 '20 at 12:09