louzin
6 months ago
8 changed files with 277 additions and 4 deletions
@ -0,0 +1,146 @@ |
|||||||
|
# Buffer |
||||||
|
其中Position和Limit的含义取决于Buffer在read还是write模式 |
||||||
|
|
||||||
|
无论何种模式,Capacity含义不变 |
||||||
|
|
||||||
|
Buffer支持的类型 |
||||||
|
- ByteBuffer |
||||||
|
- MappedByteBuffer |
||||||
|
- CharBuffer |
||||||
|
- DoubleBuffer |
||||||
|
- FloatBuffer |
||||||
|
- IntBuffer |
||||||
|
- LongBuffer |
||||||
|
- ShortBuffer |
||||||
|
![img.png](img/img.png) |
||||||
|
## Capacity |
||||||
|
内存块,Buffer的固定值 |
||||||
|
|
||||||
|
只能写入Byte,Long,Char等类型,若Buffer满了需要清除才能继续写数据 |
||||||
|
## Position |
||||||
|
写的时候代表写入数据当前位置,初始位置指向0,最大值为Capacity-1 |
||||||
|
|
||||||
|
读的时候代表读入数据当前位置,初始位置指向0 |
||||||
|
## Limit |
||||||
|
写数据时,Limit表示对Buffer最大写入多少容量,写模式下等于Capacity |
||||||
|
|
||||||
|
读数据时表示还有多少数据可读 |
||||||
|
## 分配与写数据 |
||||||
|
### 创建 |
||||||
|
|
||||||
|
```java |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.nio.CharBuffer; |
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(48); |
||||||
|
CharBuffer charBuffer=ByteBuffer.allocate(1024) |
||||||
|
``` |
||||||
|
### 写数据 |
||||||
|
#### Channel |
||||||
|
```java |
||||||
|
int bytesRead = inChannel.read(buf); |
||||||
|
//read into buffer |
||||||
|
``` |
||||||
|
#### put() |
||||||
|
```java |
||||||
|
buf.put(127); |
||||||
|
``` |
||||||
|
### flip() |
||||||
|
切换读写模式 |
||||||
|
|
||||||
|
### 读数据 |
||||||
|
#### Buffer |
||||||
|
```java |
||||||
|
int bytesWrite = inChannel.write(buf); |
||||||
|
``` |
||||||
|
#### get() |
||||||
|
```java |
||||||
|
byte aByte = buf.get(); |
||||||
|
``` |
||||||
|
## 常用方法 |
||||||
|
### rewind() |
||||||
|
position置零,重读buffer数据,limit不变 |
||||||
|
### clear() compact() |
||||||
|
clear直接清除 |
||||||
|
|
||||||
|
compact未读数据可继续读 |
||||||
|
### mark() reset() |
||||||
|
使用mark方法标记buffer中的一个特定position,通过reset()恢复这个position |
||||||
|
## 缓冲区操作 |
||||||
|
### 缓冲区分片 slice() |
||||||
|
在现有buffer缓冲区中切分出一块新区域 |
||||||
|
```java |
||||||
|
public void bufferSlice(){ |
||||||
|
ByteBuffer allocate = ByteBuffer.allocate(10); |
||||||
|
for(int i=0;i<allocate.capacity();i++){ |
||||||
|
allocate.put((byte)i); |
||||||
|
} |
||||||
|
//slice |
||||||
|
allocate.position(3); |
||||||
|
allocate.limit(7); |
||||||
|
ByteBuffer slice = allocate.slice(); |
||||||
|
for(int i=0;i<slice.capacity();i++){ |
||||||
|
slice.put((byte) i); |
||||||
|
} |
||||||
|
// allocate.position(0);//置零 |
||||||
|
// allocate.limit(allocate.capacity());//指向末尾 |
||||||
|
|
||||||
|
while (allocate.hasRemaining()){ |
||||||
|
System.out.print(allocate.get()); |
||||||
|
} |
||||||
|
System.out.println(); |
||||||
|
slice.flip(); |
||||||
|
while (slice.hasRemaining()){ |
||||||
|
System.out.print(slice.get()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
### 只读缓冲区 asReadOnlyBuffer() |
||||||
|
asReadOnlyBuffer()将任何常规缓冲区变为只读,这个方法会返回一个与原缓冲区完全相同的缓冲区,并与原缓冲区共享数据,不过只可读 |
||||||
|
```java |
||||||
|
public void readOnlyBuffer(){ |
||||||
|
ByteBuffer allocate = ByteBuffer.allocate(10); |
||||||
|
for(int i=0;i<allocate.capacity();i++){ |
||||||
|
allocate.put((byte)i); |
||||||
|
} |
||||||
|
ByteBuffer readOnly=allocate.asReadOnlyBuffer(); |
||||||
|
readOnly.flip(); |
||||||
|
while (readOnly.hasRemaining()){ |
||||||
|
System.out.print(readOnly.get()); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
若原缓冲区发生变动,只读分区随之变动 |
||||||
|
### 直接缓冲区 allocateDirect() |
||||||
|
加速I/O速度,在使用本方法创建后底层每一次I/O操作之前或之后会尝试避免将缓冲区的内容拷贝到一个中间缓冲区中,或者从一个中间缓冲区中拷贝数据 |
||||||
|
```java |
||||||
|
public void directBuffer() throws IOException { |
||||||
|
RandomAccessFile randomAccessFile = new RandomAccessFile("src/main/resources/bufferreader.txt","rw"); |
||||||
|
RandomAccessFile copy = new RandomAccessFile("src/main/resources/copy.txt","rw"); |
||||||
|
ByteBuffer byteBuffer =ByteBuffer.allocateDirect(1024); |
||||||
|
FileChannel channel = randomAccessFile.getChannel(); |
||||||
|
FileChannel channel1 = copy.getChannel(); |
||||||
|
while (true){ |
||||||
|
byteBuffer.clear(); |
||||||
|
if(channel.read(byteBuffer)==-1){ |
||||||
|
break; |
||||||
|
} |
||||||
|
byteBuffer.flip(); |
||||||
|
channel1.write(byteBuffer); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
### 内存映射文件I/O |
||||||
|
```java |
||||||
|
static private final int start=0; |
||||||
|
static private final int size=1024; |
||||||
|
public void memBuffer() throws Exception { |
||||||
|
RandomAccessFile randomAccessFile = new RandomAccessFile("src/main/resources/bufferreader.txt","rw"); |
||||||
|
FileChannel fc = randomAccessFile.getChannel(); |
||||||
|
MappedByteBuffer mappedByteBuffer= fc.map(FileChannel.MapMode.READ_WRITE,start,size); |
||||||
|
mappedByteBuffer.put(0,(byte) 97); |
||||||
|
mappedByteBuffer.put(1023,(byte) 122); |
||||||
|
randomAccessFile.close(); |
||||||
|
} |
||||||
|
``` |
After Width: | Height: | Size: 180 KiB |
@ -0,0 +1,78 @@ |
|||||||
|
package com.louzin.niodemo.bufferdemo; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import java.io.FileNotFoundException; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.RandomAccessFile; |
||||||
|
import java.nio.Buffer; |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.nio.MappedByteBuffer; |
||||||
|
import java.nio.channels.FileChannel; |
||||||
|
|
||||||
|
public class buffer3 { |
||||||
|
@Test |
||||||
|
public void bufferSlice(){ |
||||||
|
ByteBuffer allocate = ByteBuffer.allocate(10); |
||||||
|
for(int i=0;i<allocate.capacity();i++){ |
||||||
|
allocate.put((byte)i); |
||||||
|
} |
||||||
|
//slice
|
||||||
|
allocate.position(3); |
||||||
|
allocate.limit(7); |
||||||
|
ByteBuffer slice = allocate.slice(); |
||||||
|
for(int i=0;i<slice.capacity();i++){ |
||||||
|
slice.put((byte) i); |
||||||
|
} |
||||||
|
// allocate.position(0);//置零
|
||||||
|
// allocate.limit(allocate.capacity());//指向末尾
|
||||||
|
|
||||||
|
while (allocate.hasRemaining()){ |
||||||
|
System.out.print(allocate.get()); |
||||||
|
} |
||||||
|
System.out.println(); |
||||||
|
slice.flip(); |
||||||
|
while (slice.hasRemaining()){ |
||||||
|
System.out.print(slice.get()); |
||||||
|
} |
||||||
|
} |
||||||
|
@Test |
||||||
|
public void readOnlyBuffer(){ |
||||||
|
ByteBuffer allocate = ByteBuffer.allocate(10); |
||||||
|
for(int i=0;i<allocate.capacity();i++){ |
||||||
|
allocate.put((byte)i); |
||||||
|
} |
||||||
|
ByteBuffer readOnly=allocate.asReadOnlyBuffer(); |
||||||
|
readOnly.flip(); |
||||||
|
while (readOnly.hasRemaining()){ |
||||||
|
System.out.print(readOnly.get()); |
||||||
|
} |
||||||
|
} |
||||||
|
@Test |
||||||
|
public void directBuffer() throws IOException { |
||||||
|
RandomAccessFile randomAccessFile = new RandomAccessFile("src/main/resources/bufferreader.txt","rw"); |
||||||
|
RandomAccessFile copy = new RandomAccessFile("src/main/resources/copy.txt","rw"); |
||||||
|
ByteBuffer byteBuffer =ByteBuffer.allocateDirect(1024); |
||||||
|
FileChannel channel = randomAccessFile.getChannel(); |
||||||
|
FileChannel channel1 = copy.getChannel(); |
||||||
|
while (true){ |
||||||
|
byteBuffer.clear(); |
||||||
|
if(channel.read(byteBuffer)==-1){ |
||||||
|
break; |
||||||
|
} |
||||||
|
byteBuffer.flip(); |
||||||
|
channel1.write(byteBuffer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static private final int start=0; |
||||||
|
static private final int size=1024; |
||||||
|
public void memBuffer() throws Exception { |
||||||
|
RandomAccessFile randomAccessFile = new RandomAccessFile("src/main/resources/bufferreader.txt","rw"); |
||||||
|
FileChannel fc = randomAccessFile.getChannel(); |
||||||
|
MappedByteBuffer mappedByteBuffer= fc.map(FileChannel.MapMode.READ_WRITE,start,size); |
||||||
|
mappedByteBuffer.put(0,(byte) 97); |
||||||
|
mappedByteBuffer.put(1023,(byte) 122); |
||||||
|
randomAccessFile.close(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.louzin.niodemo.bufferdemo; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import java.io.FileNotFoundException; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.RandomAccessFile; |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.nio.IntBuffer; |
||||||
|
import java.nio.channels.FileChannel; |
||||||
|
|
||||||
|
public class buffertest { |
||||||
|
@Test |
||||||
|
public void buffer01() throws IOException { |
||||||
|
RandomAccessFile randomAccessFile = new RandomAccessFile("src/main/resources/bufferreader.txt", "rw"); |
||||||
|
FileChannel channel = randomAccessFile.getChannel(); |
||||||
|
ByteBuffer allocate = ByteBuffer.allocate(1024); |
||||||
|
int read = channel.read(allocate); |
||||||
|
allocate.flip(); |
||||||
|
while (allocate.hasRemaining()){ |
||||||
|
System.out.print((char) allocate.get()); |
||||||
|
} |
||||||
|
randomAccessFile.close(); |
||||||
|
} |
||||||
|
//intbuffer
|
||||||
|
@Test |
||||||
|
public void buffertest1(){ |
||||||
|
IntBuffer allocate = IntBuffer.allocate(8); |
||||||
|
//write data into buffer
|
||||||
|
for(int i=0;i<8;i++){ |
||||||
|
allocate.put(i); |
||||||
|
} |
||||||
|
allocate.flip(); |
||||||
|
while (allocate.hasRemaining()){ |
||||||
|
System.out.print(allocate.get()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,4 +0,0 @@ |
|||||||
package com.louzin.niodemo.bufferdemo; |
|
||||||
|
|
||||||
public class test { |
|
||||||
} |
|
Loading…
Reference in new issue