First I try to answer your questions. Then I will try to show you a piece of code that I created that solves your problem by blocking I / O.
Your questions
I want to write to a named pipe (already created) without blocking the reader
You do not need to block IO to solve your problem. I think this will not even help you solve your problem. Blocking I / O will also work well (perhaps even better than not blocking IO due to low concurrency). Plus blocks IO, easier to program. Your reader may / should remain blocked.
My reader is another application that may go down. If the reader really goes down, I want a neep writer application that writes a named pipe. So when the reader appears, he can resume from the place where he failed.
just put messages on the lock queue. Then write to the named pipe only when the reader reads from it (this happens automatically due to I / O blocking). No non-blocking IO file is needed when using a blocking queue. Data is transferred asynchronously from the lock queue when reading a reader, which sends your data from your writer to the reader.
Something like fopen (fPath, O_NONBLOCK) in Java
You do not need to block IO on the reader, and even if you used it. just use IO lock.
CODE SNIPPET
A created a small snippet that I think demonstrates your needs.
<strong> Components:
- Writer.java : reads lines from the console as an example. When you run the program, enter the text and then enter that will send it to your named pipe. The author will resume recording if necessary.
- Reader.java : reads lines written from your named pipe (Writer.java).
- Named pipe I assume that you created a pipe named "pipe" in the same directory.
Writer.java
import java.io.BufferedWriter; import java.io.Console; import java.io.FileWriter; import java.io.PrintWriter; import java.util.concurrent.BlockingDeque; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; import java.util.logging.Level; import java.util.logging.Logger; public class Writer { private final BlockingDeque<StringBuffer> queue; private final String filename; public static void main(String[] args) throws Exception { final Console console = System.console(); final Writer writer = new Writer("pipe"); writer.init(); while(true) { String readLine = console.readLine(); writer.write(new StringBuffer(readLine)); } } public Writer(final String filename){ this.queue = new LinkedBlockingDeque<StringBuffer>(); this.filename = filename; } public void write(StringBuffer buf) { queue.add(buf); } public void init() { ExecutorService single = Executors.newSingleThreadExecutor(); Runnable runnable = new Runnable() { public void run() { while(true) { PrintWriter w = null; try { String toString = queue.take().toString(); w = new PrintWriter(new BufferedWriter(new FileWriter(filename)), true); w.println(toString); } catch (Exception ex) { Logger.getLogger(Writer.class.getName()).log(Level.SEVERE, null, ex); } } } }; single.submit(runnable); } }
Reader.java
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class Reader { private final BufferedReader br; public Reader(final String filename) throws FileNotFoundException { br = new BufferedReader(new FileReader(filename)); } public String readLine() throws IOException { return br.readLine(); } public void close() { try { br.close(); } catch (IOException ex) { Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String[] args) throws FileNotFoundException { Reader reader = new Reader("pipe"); while(true) { try { String readLine = reader.readLine(); System.out.println("readLine = " + readLine); } catch (IOException ex) { reader.close(); break; } } } }
Alfred
source share