在非阻塞FileDescriptors上选择

时间:2013-12-10 23:57:47

标签: java android io nio

我有一个或多个非阻塞FileDescriptor对象(已经创建并从某个子系统传递给我)。我想等待,然后使用某种select()从他们读取。我如何在Java(Android)中执行此操作?我可以使用Selector类吗?

2 个答案:

答案 0 :(得分:2)

从提供的其他答案中读取评论,我看到你正在尝试使VpnService fd阻塞,在较低的Android版本中不支持。

我所做的是通过JNI代码阻止fd。希望这会有所帮助。

答案 1 :(得分:0)

看起来我们无法使用Selector s。

让我们尝试一种不同的方法。

假设您有一个方法open(),它返回您想要的FileDescriptor,但会阻止某些IO操作。您希望能够在提取FileDescriptor时继续开展业务,而无需等待此操作,并且您想知道它们什么时候准备就绪。

尝试这样的事情:

// IMPORTS
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class FileDescriptorFetcher extends Thread {
  final BlockingQueue<FileDescriptor> queue =
      new LinkedBlockingQueue<FileDescriptor>();
  // let's just pretend Openable provides FileDescriptors from open()
  final Openable[] from;
  boolean done;

  FileDescriptorFetcher(Openable[] fromThese) {
    from = fromThese;
    done = false;
    start();
  }

  @Override
  public void run() {
    for (Openable o : from)
      queue.offer(o.open());

    done = true;
  }

  public boolean isDone() {
    return done;
  }

  public boolean descriptorAvailable() {
    return !queue.isEmpty();
  }

  /* blocks if there are more descriptors to get and none are available,
   * returns null if all have been fetched already */
  public FileDescriptor fetchDescriptor() {
    return done
        ? null
        : queue.take();
  }
}

使用这个类,你只需在它的构造函数中传递一个FileDescriptor个创建者数组,它就会开始打开它们。获取到目前为止生成的所有FileDescriptor

FileDescriptorFetcher fetcher;

// init fetcher

while (fetcher.descriptorAvailable()) {
  doStuff(fetcher.fetchDescriptor());
}

尽快获得每一个FileDescriptor

while (!fetcher.isDone()) {
  doStuff(fetcher.fetchDescriptor());
}