As we had known, If we want to use traditional IO to construct server, it must block somewhere, so we had to use loop or one thread one socket mode, So nio seem it is better choice. So I want know if the nio is better choice forever?
7 Answers
IMHO, Blocking IO is generally the simplest to use, and unless you have a specific requirement which demands more from your system, you should stick with simplest option.
The next simplest option is blocking NIO, which I often prefer if I want something more efficiency or control than IO. It is still relatively simple but allows you to use ByteBuffers. e.g. ByteBuffers support little endian.
A common option is to use non-blocking NIO with Selectors. Much of the complexity this introduces can be handled by frameworks such as Netty or Mina. I suggest you use such a library if you need non-blocking IO e.g. because you have thousands of concurrent connections per server. IMHO You have thousands of connections, you should consider having more servers unless what each connection does is pretty trivial. AFAIK google go for more servers rather thousands of users per server.
The more extreme option is to use NIO2. This is even more complex and lengthy it write than non-blocking NIO. I don't know of any frameworks which support this well. i.e. it is actually faster when you do. AFAIK It appears this is worth using if you have Infiniband (which is what it was designed to support) but perhaps not worth using if you have Ethernet.

- 525,659
- 79
- 751
- 1,130
-
1Thanks for your post. I came across your answer since I am researching on the same topic. I am trying to understand the OS improvements that nio & nio2 exposes to the java programmers. A couple of them being - DMA and memory mapped files. Have you come across more of such improvements? – Andy Dufresne Mar 18 '13 at 06:29
-
Should I consider usage of NIO instead of IO in case of reading a stream that has 1000 messages in 1 second? – Maroun Apr 22 '15 at 07:44
-
2@MarounMaroun it depends on the size of the messages but I suggest using some buffering and you should be able to handle hundreds of thousands of messages per second no matter what other choices you make. Note: try to keep the messages smaller if you can. – Peter Lawrey Apr 22 '15 at 08:06
-
@PeterLawrey thanks a lot. I have an opened stream from Twitter, I'm supposed to read 1000 messages per second, but for some reason I'm getting an error saying their buffer reached its limit. By saying "using some buffering" you mean IO buffers? – Maroun Apr 22 '15 at 08:13
-
@MarounMaroun in this case, yes. Which limit did you reach? Is it possible you are reading a message which is not complete. A stream of bytes doesn't understand messages only bytes, so when you read from a stream you can get any fraction of a message even just one byte at a time. How are you handling this? – Peter Lawrey Apr 22 '15 at 08:21
-
@PeterLawrey I'm simply reading `BufferedReader#readLine` (since it's promised that I'm getting each JSON as a line, and this works - I can actually see that I'm reading full JSONs on each iteration). The limitation is from twitter: "*Force closing connection to `**.*.**.**` because it reached the maximum allowed backup (buffer size is 311298 messages)*" (if "need help" comments are bothering you please let me know :)) – Maroun Apr 22 '15 at 08:29
-
@MarounMaroun that means that twitter was sending you data faster than you are reading it. I suggest that after you read line you do nothing more in that thread than add it to a BlockingQueue. Most likely your program to parse and process the messages was too slow. – Peter Lawrey Apr 22 '15 at 08:33
-
@PeterLawrey many thanks, will try that. Last question: Is it relevant to increase the buffer size (I'm using default now), and say set it to something like 1MB? – Maroun Apr 22 '15 at 08:38
-
1@MarounMaroun you can do this but the point of the queue us so you can see that you are falling behind and perhaps take corrective action. If you are failing to keep up in the long term, more buffering and even queue won't help in itself. Buffering help.if you get bursts of activity and you can't keep up for short period but can in the long run. It smooths out the bursts of activity. – Peter Lawrey Apr 22 '15 at 12:58
-
2@PeterLawrey small update, maybe will help other visitors.. part of the problem was the machine itself (my application was deployed on AWS t2.small machine which didn't provide good networking performance, after I moved the app to more advanced machine, the amount of errors was significantly reduced. – Maroun Apr 26 '15 at 08:01
If you want non-blocking IO, NIO is not the better choice—it's the only choice in Java. Keep in mind that people still use the old IO regularly because it is way simpler to code against. NIO API is quite raw and is more of an enabling low-level technology than a client-side API. I suggest using NIO through an API that provides a simpler interface to the problems you want to solve using non-blocking IO.

- 195,646
- 29
- 319
- 436
-
So if I call Files.exit(/path/to/nfs/file) and the NFS file is stale due to some nfs mounting issues the call would not block would it? – asm Nov 21 '18 at 20:22
You would only use NIO if you can justify the inevitable complexity that it introduces. If you do not have any guidance in terms of the expected load, and also in terms of whether your product / project has the resources to maintain the relevant code, then your should err on the side of caution and use IO.
To give my answer some weight, I have just spent three months maintaining and bug fixing an integration layer where raw Java NIO (i.e. no overarching framework was used) was used. The design was based, in essence, on client threads adding messages to a queue and a small number of worker threads performing their NIO magic and then passing replies back to client threads in an event-based manner. In retrospect, I cannot justify the original decision to use NIO, since it became a distraction that ate significant amounts of time that should have been spent on higher level business logic.

- 319
- 2
- 12
A little late, but personally, I use NIO even for the regular "everyday" file handling. So, I use things like:
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);
and it works fine for me. I prefer Path instead of the old File because of methods like relativize or resolveSibling.
Doesn't strike me as more complicated than IO.

- 2,960
- 9
- 33
- 64
You can use any of this, unless you are going to create "super fast" server.
Of course a good approach here is to use nio, since it's new and modern way to write multi-client servers for high throughput tasks.

- 601
- 8
- 21
-
1Questionable. There's a lot of research that suggests the opposite. Novelty isn't always an improvement. – user207421 Oct 15 '12 at 09:25
-
1
-
@EJP Sure, you are absolutely right, but here there is no doubt. If author is going to implement a server for his own needs, which is not going to cover more than 100 clients, then there is no need to use nio. Old school way is just simpler to use and understand than non-blocking async model. – Max Oct 15 '12 at 09:31
-
@MyNameIsTooCommon It means nothing. Another question if you are using nio for appropriate tasks. – Max Oct 15 '12 at 09:36
-
Some advantages of the NIO.2 API over the legacy java.io.File
class for working with files:
- Supports file system–dependent attributes.
- Allows you to traverse a directory tree directly.
- Supports symbolic links.
For specific use cases and more details, you can see this article
Traditional IO is easy and simplified code, NIO is more complicated but more flexible. In my case i prefer use IO for small streaming and NIO for large streaming but nio is really more complex
with NIO i have to create an entire package to manage it instead io package that i directly use snippet

- 190
- 2
- 15
-
1I disagree. See this: `Files.readAllLines(Paths.get(filename), Charset.forName("UTF-8"));`. In one line you've parsed the file and put everything into a list; this would be a class-long exercise in old IO. – Evil Washing Machine Apr 07 '16 at 12:41
-
well @EvilWashingMachine i think ur right :) but.. if we are talking about parsing a file and fetch information, in any case with your method, you will do the "class-long exercise in old IO" ^^ – Andrea Bori Apr 09 '16 at 09:12