Java NIO - 零拷贝
NIO零拷贝
使用传统的IO 方法传递一个大文件
使用NIO 零拷贝方式传递(transferTo)一个大文件
看看两种传递方式耗时时间分别是多少
传统IO方法
服务端代码
public class OldServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(1212);
System.out.println("服务端启动已启动......");
while (true) {
// 等待连接
Socket socket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
// 接收消息
try (InputStream inputStream = socket.getInputStream()){
byte[] result = new byte[1024];
while (true) {
int read = inputStream.read(result);
if (read == -1) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端代码
public class OldClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 1212);
OutputStream outputStream = socket.getOutputStream();
// 文件大小为300MB
File file = new File("D:\\电子书\\深入理解Apache Dubbo与实战.pdf");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
long total = 0;
long startTime = System.currentTimeMillis();
while (true) {
long readCount = fileInputStream.read(buffer);
if (readCount == -1) {
break;
}
total += readCount;
outputStream.write(buffer);
}
outputStream.flush();
System.out.println("发送总字节数: " + total + ", 耗时: " + (System.currentTimeMillis() - startTime));
fileInputStream.close();
socket.close();
}
}
NIO零拷贝
服务端代码
public class NewIOServer {
public static void main(String[] args) throws Exception {
InetSocketAddress address = new InetSocketAddress(1313);
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(address);
System.out.println("服务端启动已启动......");
//创建buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
while (true) {
SocketChannel socketChannel = serverSocketChannel.accept();
int readcount = 0;
while (-1 != readcount) {
try {
readcount = socketChannel.read(byteBuffer);
}catch (Exception ex) {
// ex.printStackTrace();
break;
}
//
byteBuffer.rewind(); //倒带 position = 0 mark 作废
}
}
}
}
客户端代码
public class NewIOClient {
public static void main(String[] args) throws Exception {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 1313));
// 文件大小为300MB
String filename = "D:\\电子书\\深入理解Apache Dubbo与实战.pdf";
//得到一个文件channel
FileChannel fileChannel = new FileInputStream(filename).getChannel();
//准备发送
long startTime = System.currentTimeMillis();
// 在linux下,一次transferTo 就可以完成传输
//transferTo 底层使用到零拷贝
// long transferCount = fileChannel.transferTo(0, fileChannel.size(), socketChannel);
//在windows下,一次ransferTo 只能发送8m , 就需要分段传输文件
long total = 0;
long position = 0; // 读取位置
while (true) {
long transferCount = fileChannel.transferTo(position, fileChannel.size(), socketChannel);
if (transferCount > 0) {
position = position + transferCount;
total = total + transferCount;
} else {
break;
}
}
System.out.println("发送的总的字节数 =" + total + " 耗时:" + (System.currentTimeMillis() - startTime));
//关闭
fileChannel.close();
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接