Accessing a file in 'read only' mode

R

Rob McCready

I've been stuck all day on what certainly appears to be an easy
question. I have a Java process that needs to read from a file while
another process simultaneously writes to it. I don't care if I read
dirty data. I just don't want to prevent the writing process to be
locked by the OS from writing.

I'm using a java.io.FileReader and then passing it into a
java.io.BufferedReader. Then I'm calling .readLine() on the
BufferedReader. Now, before I close all the streams and go out of
scope, I can't open the file with, say Word, and then save it in Word.
This is because the OS is locking it out because another process is
reading from it.

I've scrapped over the JDK and can't find any leads on how to do
something which I thought would be pretty trivial.

OS - Windows XP
Java 1.4.1

Any help is greatly appreciated.
 
M

Matt Humphrey

Rob McCready said:
I've been stuck all day on what certainly appears to be an easy
question. I have a Java process that needs to read from a file while
another process simultaneously writes to it. I don't care if I read
dirty data. I just don't want to prevent the writing process to be
locked by the OS from writing.

I'm using a java.io.FileReader and then passing it into a
java.io.BufferedReader. Then I'm calling .readLine() on the
BufferedReader. Now, before I close all the streams and go out of
scope, I can't open the file with, say Word, and then save it in Word.
This is because the OS is locking it out because another process is
reading from it.

I've scrapped over the JDK and can't find any leads on how to do
something which I thought would be pretty trivial.

You've described your problem as needing to have one process read from a
file while another reads it, but your example is about reading from a file
and then opening and saving it through Word. File locking is part of the OS
and not managed through Java, but there are some solutions for this. If the
problem is like your example with Word, simply copy the file and read the
copy. Let Word open the original.

If your problem is more like a writing process passing information to a
reading process and you can modify the program that writes (and the file
isn't too large), have the writing program periodically close the file and
copy it to a related name. The reading process should read from the copy.
If the writing process creates the file anew (like a status file or report)
rather than updating it, the easiest solution is after writing the file to
rename it for reading.

If you can't modify the writer, you may need an tool that can copy an open
file. There are backup programs (e.g. Retrospect) that can backup open
files, so it's possible. If you can use a separate tool to copy the file,
your program can read it at its convenience.

Good luck,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
R

Rob McCready

Roedy Green said:
Java is completely silent on what it does vis a vis locking out other
processes when files are open. I would try using a RandomAccessFile.
It is better designed for simultaneous read/write. Perhaps it won't
lock. see http://mindprod.com/fileio.html for sample code.

I tried this one as well and I still have the same problem. I've even
tried using a java.io.FilePermission object and explicitly telling the
VM that I only want read access to the file in question. Still no go.
The second process is still prevented from writing to the file I am
just 'looking' at :(

My guess is that this is one of those Operating System specific
things, since a colleage claims that I won't run into this problem on
LINUX. Does this mean that I need to use some JNI calls to tell the
OS that I don't care about dirty reads? Apparently, Notepad does
this, since I can open a file in Notepad and edit it with another
application.

Thanks anyways Roedy.
 
R

Roedy Green

My guess is that this is one of those Operating System specific
things, since a colleage claims that I won't run into this problem on
LINUX.

In windows the JVM designers had the choice of which style of open to
use vis a vis locking and apparently chose this one rather than a full
share.

So what do you do, given that Java has no facilities to control file
locking?

You write a little JNI that opens a file with full share. Keep it
simple. It just reads or written N bytes at a given offset.

If you need help with that, I would write you such a class for $50 US.
 
R

Roedy Green

This is because the OS is locking it out because another process is
reading from it.

I just had another thought. Check the way you opened the NON-Java
file. You may be triggering a lock by requesting exclusive access.
In other words, it's not Java's fault.
 
R

Rob McCready

Matt Humphrey said:
You've described your problem as needing to have one process read from a
file while another reads it, but your example is about reading from a file
and then opening and saving it through Word. File locking is part of the OS
and not managed through Java, but there are some solutions for this. If the
problem is like your example with Word, simply copy the file and read the
copy. Let Word open the original.

If your problem is more like a writing process passing information to a
reading process and you can modify the program that writes (and the file
isn't too large), have the writing program periodically close the file and
copy it to a related name. The reading process should read from the copy.
If the writing process creates the file anew (like a status file or report)
rather than updating it, the easiest solution is after writing the file to
rename it for reading.

If you can't modify the writer, you may need an tool that can copy an open
file. There are backup programs (e.g. Retrospect) that can backup open
files, so it's possible. If you can use a separate tool to copy the file,
your program can read it at its convenience.

Good luck,
Matt Humphrey (e-mail address removed) http://www.iviz.com/

Bummer! I knew that I could do this (just copy the file and read from
the copy and when I'm done delete it) but it just feels hacky. I
really wish there were some way of doing this cleanly through the JDK.
Oh well... wishful thinking ;(

Thanks for the help Matt!
 
M

Michiel Konstapel

My guess is that this is one of those Operating System specific
things, since a colleage claims that I won't run into this problem on
LINUX. Does this mean that I need to use some JNI calls to tell the
OS that I don't care about dirty reads? Apparently, Notepad does
this, since I can open a file in Notepad and edit it with another
application.

I think Notepad just slurps the entire file into memory at startup and
then closes it again.
Michiel
 
R

Roedy Green

I think Notepad just slurps the entire file into memory at startup and
then closes it again.

Word on the other hand seems to lock files. It might even lock them
after you close them, until you exit word. I vaguely recall swearing
at Word for being overly eager about locking. It appears to copy the
file, or at least some of the file to a temporary spill file while you
are editing it.
 
R

Rob McCready

Roedy Green said:
I just had another thought. Check the way you opened the NON-Java
file. You may be triggering a lock by requesting exclusive access.
In other words, it's not Java's fault.

I think that this is along the lines of the problem. After a couple
of days of poking around, I came up with a solution using the java.nio
and java.nio.channel packages (I was using the java.io package).

Below is code that I patched together from web examples which
'apparently' do not lock the file from another application. Now it
solves the problem by putting the file contents directly into memory,
but I don't know if I still have a problem if another process requests
to write to the file while I am loading it into memory... hmmm...

<Code>

try
{
File file = new File("hack.txt");
FileChannel fileChannel = new FileInputStream(file).getChannel();
int filesize = (int) fileChannel.size();
byte[] data = new byte[filesize];

ByteBuffer mappedFile = ByteBuffer.allocate(filesize);
fileChannel.read(mappedFile);
fileChannel.close();

mappedFile.position(0);
mappedFile.get(data);
String contents = new String(data);
System.out.println(contents);
}
catch (Exception e)
{
e.printStackTrace();
}

</Code>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top