I am creating a quick bridge between two separate programs.
One program writes to a file, while my program concurrently reads from it.
It seems that as soon as I call the first read the writing is blocked entirely.
Why is this occurring and what is the workaround?
// Create Named Pipe
Runtime.getRuntime.exec("mkfifo /tmp/mypipe")
val stream = new FileInputStream("/tmp/mypipe")
val in = new BufferedReader(new InputStreamReader(stream))
// File opened for reading. No blocking at this point.
while (true) {
println(in.readLine())
// File read. Now blocking.
}
Update:
This file is actually a named pipe created with mkfifo /tmp/mypipe
. I tried using this with a regular File
and it worked just fine - all data displayed.
I am using a named pipe because I don't want the disk IO overhead.
In Java, a file lock can be obtained using FileChannel , which provides two methods — lock() and tryLock() — for this purpose. The lock() method acquires an exclusive lock on entire file, whereas the lock(long position, long size, boolean shared) method can be used to acquire a lock on the given region of a ile.
Exclusive Locks. As we've already learned, while writing to a file, we can prevent other processes from reading or writing to it by using an exclusive lock. We get exclusive locks by calling lock() or tryLock() on the FileChannel class.
int read() − This simply reads data from the current InputStream and returns the read data byte by byte (in integer format). This method returns -1 if the end of the file is reached. int read(byte[] b) − This method accepts a byte array as parameter and reads the contents of the current InputStream, to the given array.
If I had to bet, I'd say it's a buffering problem.
Initially I was thinking that BufferedReader
might try to fill its entire buffer, but it looks like it's happy as long as it's read something. See the fill()
method.
If you're using readLine()
, there's also the question of whether the input you're getting contains newlines.
The other thing that could be happening, depending on how much output the source program produces, is to do with pipe buffering. Would this answer help?
You can also try ending the source program (e.g. ^C
or such) and then seeing if the destination program prints anything.
This page suggests that buffering could be an issue:
However, if a buffered write is used, the buffer is not made available to the reader until the buffer is flushed. This flushing occur.s when more data is written to the buffer than the maximum buffer size (BUFSIZ set in stdio.h), or when the pipe is closed by the writer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With