首先,我尝试回答您的问题。接下来我将尝试向您展示我创建的代码 sn-p 使用阻塞 IO 解决您的问题。
您的问题
我想写一个命名管道
(已经创建)没有阻塞
读者
您不需要非阻塞 IO 来解决您的问题。我认为它甚至不能帮助你解决你的问题。阻塞 IO 也会运行良好(由于并发性低,可能比非阻塞 IO 更好)。一个优点是阻塞 IO 更容易编程。您的读者可以/应该保持屏蔽状态。
我的阅读器是另一个应用程序
可能会下降。如果读者真的去了
下来,我希望作家应用程序
neep 写入命名管道。这样当阅读器出现时,它可以从失败的地方恢复。
只需将消息放入阻塞队列即可。接下来仅在读取器读取命名管道时写入(由于阻塞 IO 而自动发生)。使用阻塞队列时不需要非阻塞文件 IO。当读取器正在读取时,数据从阻塞队列异步传递,这会将您的数据从写入器发送到读取器。
类似于 fopen(fPath,
Java 中的 O_NONBLOCK)
您不需要阅读器上的非阻塞 IO,即使您使用它也是如此。只需使用阻塞 IO。
代码片段
A 创建了一个小 sn-p,我相信它可以证明您的需求。
组件:
-
Writer.java:例如从控制台读取行。当您启动程序时输入文本,然后输入将其发送到您的命名管道。如有必要,作者将继续写作。
-
Reader.java:读取从命名管道 (Writer.java) 写入的行。
-
命名管道:我假设您在同一目录中创建了一个名为“管道”的管道。
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;
}
}
}
}