Java中的非阻塞文件IO [英] Non-Blocking File IO in Java

查看:89
本文介绍了Java中的非阻塞文件IO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个命名管道(已经创建)而不会阻塞读取器。我的读者是另一个可能会失败的应用程序。如果读者确实失败了,我希望编写器应用程序继续写入该命名管道。类似Java中的东西

I want to write to a named pipe (already created) without blocking on the reader. My reader is another application that may go down. If the reader does go down, I want the writer application to keep writing to that named pipe. Something like a this in Java

fopen(fPath, O_NONBLOCK)

因此,当读者出现时,它可能会从失败的地方恢复。

So that when the reader comes up, it may resume from where it failed.

推荐答案

首先,我试着回答你的问题。接下来,我将尝试向您展示我创建的代码片段,使用阻止IO解决您的问题。

First I try to answer your questions. Next I will try to show you a code snippet I created that solves your problem using blocking IO.

我想写一个命名管道
(已经创建)而不阻塞
读者

I want to write to a named pipe (already created) without blocking on the reader

您不需要非阻塞IO来解决您的问题。我认为它甚至无法帮助您解决问题。阻止IO也将运行良好(可能甚至比非阻塞IO更好,因为并发性低)。一个加号是阻止IO更容易编程。您的读者可以/应该保持阻止。

You don't need non blocking IO to solve your problem. I think it can not even help you solve your problem. Blocking IO will also run good(maybe even better then non blocking IO because of the low concurrency). A plus is blocking IO is easier to program. Your reader can/should stay blocking.


我的读者是另一个
可能会下降的应用程序。如果读者确实下了
,我希望编写器应用程序以
写入命名管道。因此,当读者出现时,它可以从失败的地方恢复。

My reader is another application that may go down. If the reader does go down, I want the writer application to neep writing to the named pipe. So that when the reader comes up, it may resume from where it failed.

将消息放入阻塞队列中。当读者从中读取命名管道时,仅写入 <由于阻塞IO而自动发生。使用阻塞队列时不需要非阻塞文件IO。当读者正在阅读时,数据是从阻塞队列异步传递的,这会将你的数据从你的作者发送到读者。

just put the messages inside a blocking queue. Next write to the named pipe only when the reader is reading from it(happens automatically because of blocking IO). No need for non-blocking file IO when you use a blocking queue. The data is asynchronous delivered from the blocking queue when a reader is reading, which will sent your data from your writer to the reader.


Something像Java中的fopen(fPath,
O_NONBLOCK)

Something like a fopen(fPath, O_NONBLOCK) in Java

您不需要读取器上的非阻塞IO即使你用过它。只使用阻止IO。

You don't need non-blocking IO on the reader and even if you used it. just use blocking IO.

创建了一个小片段,我相信它可以展示你的需求。

A created a little snippet which I believe demonstrates what your needs.

组件:


  • 作家.java :从控制台读取行作为示例。当您启动程序时,输入文本,然后输入,将其发送到您的命名管道。如有必要,作者将继续写作。

  • Reader.java :读取从命名管道(Writer.java)写入的行。

  • 命名管道:我假设您在同一目录中创建了一个名为pipe的管道。

  • Writer.java: reads lines from console as an example. When you start program enter text followed by enter which will sent it to your named pipe. The writer will resume writing if necessary.
  • Reader.java: reads lines written from your named pipe(Writer.java).
  • Named pipe: I assume you have 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;
            }
        }
    }
}

这篇关于Java中的非阻塞文件IO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆