2010-10-17 181 views

回答

9

UNIX不支持文件的非阻塞I/O,请参见Non-blocking I/O with regular files。由于Java应该(至少试图)在所有平台上提供相同的行为,因此FileChannel不实现SelectableChannel

但是Java 7将包含一个新的AsynchronousFileChannel类,该类支持异步文件I/O,这是与非阻塞I/O不同的机制。它的一个实现WindowsAsynchronousFileChannelImpl受益于Windows上的非阻塞I/O API(请参阅Asynchronous I/O in Windows)。

与此同时,您可以使用多个线程来实现相同的效果。但是这已经在SimpleAsynchronousFileChannelImpl中实现了,它可以跨所有操作系统使用。

通常只有插座和管道通过select()机制真正支持非阻塞I/O。


@Trying评论从而:

“AsynchronousFileChannel支持异步I/O而不是无阻塞”。

我认为,异步I/O(例如使用FutureCompletionHandler)是非阻塞的I/O的形式。

  • 它不会阻止线程在通道上执行read(...)呼叫。您可以使用Future.isDone()以避免以后阻止。

(当然,I/O使用Selector可以是异步的太...取决于你如何使用API​​)。

相反,如果你读一个FileChannel并没有当前可用的数据,线程块...(通常)直到数据可用。

+1

+1。 asynchronousFileChannel支持异步I/O而非非阻塞。请检查。谢谢。 – Trying 2013-07-12 00:27:59

+1

@Trying - 我已解决您的评论。 (我并不完全同意......) – 2013-07-12 05:20:46

+0

我在['WindowsAsynchronousFileChannelImpl']中看不到任何内容(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40 -b43/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java)“受益于Windows上的非阻塞API”。请澄清,或更正。异步I/O更像是阻塞在单独线程上执行的I/O,而非像非阻塞I/O那样。 – EJP 2017-05-23 11:16:13

1

简而言之,大多数操作系统不会将常规文件视为可以阻止的内容 - 因此它们不允许您明确地将它们设置为非阻止状态。

+0

文件I/O只能被阻塞,因为它们被认为是非阻塞的?你是什​​么意思?在编程中,每个操作都被阻止。 – Val 2012-06-22 08:33:56

+1

@Val我同意这里的措辞不是最好的。在编程中,并不是每个操作都被阻塞(从某种意义上讲,它会将进程或线程置于阻塞状态)。我的意思是,对于一个普通的文件,操作系统级别的API假定read()/ write()/ open()和其他对常规文件的调用是非阻塞的,但这是一个错误的假设。常规/标准操作系统级别的API无法将文件的句柄从阻塞更改为非阻塞。 (这是你可以用插座和管柄来做的事情)。 – nos 2012-06-22 09:28:45

+0

@nos操作系统级别的API假设'read()/ write()/ open()'和其他调用是* blocking *。不清楚你在说什么。 – EJP 2017-05-23 11:17:17