3.6 Introduction to Channels
Channels: defined by java.nio.Channels Channel indicates the open connection between the I/O source and the destination. A Channel is similar to a traditional stream. However, the Channel itself cannot access the data directly; it can only interact with buffers
3.7 Channel Model
3.8 Channel implementation classes
-
FileChannel: Channel for reading, writing, mapping, and manipulating files.
-
DatagramChannel: Reads and writes data channels on the network through UDP.
-
SocketChannel: Reads and writes data on the network through TCP.
-
ServerSocketChannel: Listens for incoming TCP connections and creates a SocketChannel for each incoming connection
3.8.1 Obtaining channels
One way to get channels is to call the getChannel() method on objects that support channels. The following classes support channels:
-
FileInputStream
-
FileOutputStream
-
RandomAccessFile
-
DatagramSocket
-
Socket
-
ServerSocket
Another way to get a channel is to get a byte channel using the static method newByteChannel() of the Files class. Or the static method open() for the channel opens and returns the specified channel.
3.8.2 Data transmission over channels
- Write Buffer data to Channel
- Read data from Channel to Buffer
1. Copy files using channels (indirect buffer)
/** * Copy files using channels (non-direct buffers) */
@Test
public void test01(a) {
FileInputStream fis = null;
FileOutputStream fos = null;
//1. Obtain the channel
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fis = new FileInputStream("d:/1.mp4");
fos = new FileOutputStream("d:/2.mp4");
inChannel = fis.getChannel();
outChannel = fos.getChannel();
//2. Allocate a buffer of the specified size
ByteBuffer buf = ByteBuffer.allocate(1024);
//3. Store channel data in a buffer
while(inChannel.read(buf) ! = -1) {
// Switch the data read mode
buf.flip();
//4. Write buffer data to channeloutChannel.write(buf); buf.clear(); }}catch (IOException e) {
e.printStackTrace();
} finally {
if(fis ! =null) {
try {
fis.close();
} catch(IOException e) { e.printStackTrace(); }; }if(fos ! =null) {
try {
fos.close();
} catch(IOException e) { e.printStackTrace(); }; }if(inChannel ! =null) {
try {
inChannel.close();
} catch(IOException e) { e.printStackTrace(); }; }if(outChannel ! =null) {
try {
outChannel.close();
} catch(IOException e) { e.printStackTrace(); }; }}}Copy the code
2. Use the direct buffer to copy files (memory-mapped files) ps: not recommended
/** * Use the direct buffer to complete the file copy (memory mapped file) */
@Test
public void test02(a) {
//1. Obtain the channel
FileChannel inChannel = null;
FileChannel outChannel = null;
//2. Memory mapped file
MappedByteBuffer inMapperBuf = null;
MappedByteBuffer outMapperBuf = null;
try {
inChannel = FileChannel.open(Paths.get("d:/1.mp4"),
/ / read
StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("d:/3.mp4"),
/ / read
StandardOpenOption.READ,
/ / create
StandardOpenOption.CREATE_NEW,
/ / write
StandardOpenOption.WRITE);
// Write data directly to the buffer
byte[] dst = new byte[inMapperBuf.limit()];
inMapperBuf.get(dst);
outMapperBuf.put(dst);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inChannel ! =null) {
try {
inChannel.close();
} catch(IOException e) { e.printStackTrace(); }}if(outChannel ! =null) {
try {
outChannel.close();
} catch(IOException e) { e.printStackTrace(); }}}}Copy the code
3. Data transfer between channels (direct buffer) transferFrom/transferTo
/** * Data transfer between channels (direct buffer) */
@Test
public void test03(a) {
//1. Obtain the channel
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("d:/1.mp4"));
outChannel = FileChannel.open(Paths.get("d:/4.mp4"),
StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// Choose one or the other, pay attention to the API
// inChannel.transferTo(0, inChannel.size(), outChannel);
outChannel.transferFrom(inChannel, 0, inChannel.size());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inChannel ! =null) {
try {
inChannel.close();
} catch(IOException e) { e.printStackTrace(); }}if(outChannel ! =null) {
try {
outChannel.close();
} catch(IOException e) { e.printStackTrace(); }}}}Copy the code