What is zero copy?
Let's start with a look at traditional I/O operations.
Let's say that the user process now copies one file to another.
Then the user program must first read this file into memory, and then write the data in memory to another file.
However, file read-in memory is not directly read into the memory of user processes, but read into the memory of the operating system kernel first, and then read from the memory area of the operating system kernel to the memory of user processes.
Correspondingly, writing files is not a file written directly to disk, but a user process first transfers its own memory data to the memory of the operating system kernel, and then writes from the memory area of the operating system kernel to disk. And there are many system calls involved.
So the seemingly simple operation is divided into at least four parts
1 Disk File Read-in Operating System
2 Operating System Reads User Processes
3 User Processes Write to Operating System
4 Operating System Writes Disk Files
Is zero copy different from traditional I/O?
Zero copy means that when transferring a file, it does not need to read the file to the user process for processing, but directly reads the file to one memory area of the operating system, then moves to another memory area of the operating system, and finally writes the file.
In this way, the steps become as follows:
1 Disk File Read-in Operating System
2. The operating system writes data to another area of the operating system.
3 Operating System Writes Disk Files
Although only one step is missing, it not only reduces the time loss of data movement, but also reduces the number of system calls, thus greatly shortening the time.
For a more detailed explanation, see https://blog.csdn.net/u010530...
How to implement zero copy in java?
This brings us to the FileChannel.transferTo() method in java nio, which transfers data from FileChannel to another channel using zero-proximity technology. This other channel is often File Channel, but Socket Channel can do the same: ____________
Simple implementation (static download files, can not change the downloaded files according to user instructions. )
The code is as follows:
Single-threaded version:
package qiuqi.filedownloadtest; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator; public class FileServer { public static void main(String[] args) throws IOException { startServer(); } public static void startServer() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress(9999)); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); if(key.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); try (FileInputStream in = new FileInputStream("C:\\Users\\dell\\Desktop\\ZOL Mobile phone data(1).rar")){ in.getChannel().transferTo(0,in.getChannel().size(),socketChannel); socketChannel.close(); } catch (IOException e){e.printStackTrace();} } } } } }
Multithread version:
package qiuqi.filedownloadtest; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FileServer { static ExecutorService threadpool = Executors.newCachedThreadPool(); public static void main(String[] args) throws IOException { startServer(); } public static void startServer() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress(9999)); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); if(key.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); threadpool.execute(new Runnable() { @Override public void run() { try (FileInputStream in = new FileInputStream("C:\\Users\\dell\\Desktop\\ZOL Mobile phone data(1).rar")){ in.getChannel().transferTo(0,in.getChannel().size(),socketChannel); socketChannel.close(); } catch (IOException e){e.printStackTrace();} } }); } } } } }
The code is not explained. If you've learned java nio, it's easy to understand the above program.
If you are not familiar with java nio server programming, please learn before you watch.
Finally, I want to say that java NIO is really NEW IO, the new IO, not NonBlocking IO, the non-blocking IO. Because in this system, it not only provides non-blocking programming model, but also provides new technologies such as zero-copy, memory mapping (for the operating system, it has long been).