我们知道,如果我们想要使用传统的IO来构建服务器,它必须在某个地方阻塞,所以我们不得不使用循环或一个线程一个套接字模式,因此NIO似乎是更好的选择。那么我想知道,NIO是否永远是更好的选择?
在我看来,阻塞式IO通常是最简单易用的选项,除非您的系统有特定要求需要更多功能,否则应该坚持使用最简单的选项。
下一个最简单的选项是阻塞NIO,如果我想要比IO更高效或有更多控制权,我经常会选择它。 它仍然相对简单,但允许您使用ByteBuffers。例如,ByteBuffers支持小端。
一种常见的选择是使用带有Selectors的非阻塞NIO。 这引入的大部分复杂性可以由像Netty或Mina这样的框架处理。如果您确实需要非阻塞IO(例如因为每个服务器有数千个并发连接),建议您使用此类库。 在我看来,如果您拥有数千个连接,则应考虑增加更多服务器,除非每个连接所做的事情相当琐碎。据我所知,谷歌选择更多服务器而不是每个服务器数千个用户。
更极端的选择是使用NIO2。这比非阻塞NIO甚至更加复杂和冗长,我不知道有哪些框架能够很好地支持它。也就是说,当您使用时,它实际上更快。据我所知,如果您拥有Infiniband(这是它设计支持的内容),则值得使用,但如果您拥有以太网,则可能不值得使用。
虽然晚了一点,但我个人即使是对于常规的“日常”文件处理,也使用NIO。因此,我使用以下内容:
1. if(Files.notExists(path)) { }
2. Files.createDirectory(path);
3. Files.newInputStream(path) targetPath.resolve("somefile.txt");
4. Files.newBufferedWriter(path, charset);
5. DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
对我来说这很好用。由于有relativize或resolveSibling等方法,我更喜欢Path而不是旧的File。
我觉得它并不比IO更复杂。
NIO.2 API相对于旧的java.io.File
类用于文件操作方面有以下优势:
有关具体用例和更多详细信息,您可以查看this文章。
传统IO是容易和简化的代码,NIO更加复杂但更加灵活。 在我的情况下,我更喜欢使用IO进行小流式处理,而使用NIO进行大流式处理,但是nio确实更加复杂。
使用NIO时,我必须创建一个完整的包来管理它,而使用IO包则可以直接使用片段。
Files.readAllLines(Paths.get(filename), Charset.forName("UTF-8"));
。在一行中,你已经解析了文件并将所有内容放入列表中;而在旧的IO中,这将是一个类长的练习。 - Evil Washing Machine