java nio 的读写操作代码示例
来源:互联网 发布:炒美股用什么软件 编辑:程序博客网 时间:2024/05/21 10:03
package cn.ac.yangge.service;import cn.ac.yangge.unity.AnalysisData;import cn.ac.yangge.unity.ByteBufferPrint;import org.springframework.stereotype.Service;import java.io.*;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.*;import java.util.concurrent.Callable;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;/** * Created by yangge on 2017/5/26 0026. */@Service("tcpService")public class TcpService { // 主入口 public static void main() throws IOException { sockectChannelSever(); } //使用serversocketchannel 非程阻塞 public static void sockectChannelSever() { int port = 8888;//端口 ServerSocketChannel serverSocketChannel; Selector selector; try { serverSocketChannel = ServerSocketChannel.open(); ServerSocket ss = serverSocketChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); ss.bind(address); serverSocketChannel.configureBlocking(false); selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { e.printStackTrace(); return; } while (true) { try { selector.select(); } catch (IOException e) { e.printStackTrace(); break; } Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); try { if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); System.out.println("Accepted connection from " + client); client.configureBlocking(false); SelectionKey clientKey = client.register(selector, SelectionKey.OP_READ); ByteBuffer buffer = ByteBuffer.allocate(100); clientKey.attach(buffer); } if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer output = (ByteBuffer) key.attachment(); client.read(output); output.flip(); byte[] byteArray=output.array(); for(byte b:byteArray){ System.out.println(b); } System.out.println(ByteBufferPrint.getString(output)); } } catch (IOException ex) { key.cancel(); try { key.channel().close(); } catch (IOException e) { } } } } }}
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:
- 打开一个SocketChannel并连接到互联网上的某台服务器。
- 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
打开 SocketChannel
下面是SocketChannel的打开方式:
1
SocketChannel socketChannel = SocketChannel.open();
2
socketChannel.connect(
new
InetSocketAddress(
"http://jenkov.com"
,
80
));
关闭 SocketChannel
当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:
1
socketChannel.close();
从 SocketChannel 读取数据
要从SocketChannel中读取数据,调用一个read()的方法之一。以下是例子:
1
ByteBuffer buf = ByteBuffer.allocate(
48
);
2
int
bytesRead = socketChannel.read(buf);
首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。
然后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。
写入 SocketChannel
写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。示例如下:
01
String newData =
"New String to write to file..."
+ System.currentTimeMillis();
02
03
ByteBuffer buf = ByteBuffer.allocate(
48
);
04
buf.clear();
05
buf.put(newData.getBytes());
06
07
buf.flip();
08
09
while
(buf.hasRemaining()) {
10
channel.write(buf);
11
}
注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法无法保证能写多少字节到SocketChannel。所以,我们重复调用write()直到Buffer没有要写的字节为止。
非阻塞模式
可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。
connect()
如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。像这样:
1
socketChannel.configureBlocking(
false
);
2
socketChannel.connect(
new
InetSocketAddress(
"http://jenkov.com"
,
80
));
3
4
while
(! socketChannel.finishConnect() ){
5
//wait, or do something else...
6
}
write()
非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。前面已经有例子了,这里就不赘述了。
read()
非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。
调试的时候想要转化byteBuffer?
提供给你两个方法
String 转换 ByteBuffer:
public static ByteBuffer getByteBuffer(String str) {
return ByteBuffer.wrap(str.getBytes());
}
ByteBuffer 转换 String:
public static String getString(ByteBuffer buffer) {
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try {
charset = Charset.forName("UTF-8");
decoder = charset.newDecoder();
//用这个的话,只能输出来一次结果,第二次显示为空
// charBuffer = decoder.decode(buffer);
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
return charBuffer.toString();
} catch (Exception ex) {
ex.printStackTrace();
return "error";
}
}
想要直接转化为byte[] ?
可以直接使用byteBuffer.array();
遇到的坑:
SelectionKey clientKey = client.register(selector, SelectionKey.OP_READ);在配置selectionKey的时候,之前是用了Selection.OP_WRITE的,这导致keys的事件集合中一直存在一个isWritable事件,原因是:
key.isWritable()是表示Socket可写,网络不出现阻塞情况下,一直是可以写的,所认一直为true.一般我们不注册OP_WRITE事件.
- java nio 的读写操作代码示例
- java:NIO读写文件的示例
- NIO的读写示例
- java NIO代码示例
- JAVA NIO的示例
- NIO读写文件示例
- Java读写XML代码示例
- (译)java NIO 示例代码
- JAVA NIO文件映射、通道、流读写文件示例
- NIO文件读写操作
- TCP/NIO示例代码
- NIO Buffer代码示例
- Java NIO 的简单读写 以及理解
- Java 读写xml文件代码示例
- JAVA文件操作类和文件夹的操作代码示例
- 技术贴:java nio的示例
- Java NIO框架--Netty4的简单示例
- Java NIO框架--Netty4的简单示例
- 剑指offer 31 连续子数组的最大和
- C语言中浮点数向零舍入取整的方法
- 使用Intellij IDEA 和maven创建web项目webapp全过程
- java数据解析
- SCDN博客的转载方法
- java nio 的读写操作代码示例
- 自定义画圆
- 【51Nod1967】路径定向
- hive安装问题01
- 优秀博客收藏
- JAVA中的定时器
- 算法提高 ADV-103 逆序排列
- 嚼得菜根做得大事·《菜根谭》·五
- html界面显示Toast