Browse Source

buffer rend

master
louzin 6 months ago
parent
commit
249278e578
  1. 8
      pom.xml
  2. 146
      src/doc/buffer.md
  3. BIN
      src/doc/img/img.png
  4. 78
      src/main/java/com/louzin/niodemo/bufferdemo/buffer3.java
  5. 39
      src/main/java/com/louzin/niodemo/bufferdemo/buffertest.java
  6. 4
      src/main/java/com/louzin/niodemo/bufferdemo/test.java
  7. 3
      src/main/resources/bufferreader.txt
  8. 3
      src/main/resources/copy.txt

8
pom.xml

@ -6,4 +6,12 @@
<version>1.0-SNAPSHOT</version>
<name>Archetype - nioDemo</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

146
src/doc/buffer.md

@ -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();
}
```

BIN
src/doc/img/img.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

78
src/main/java/com/louzin/niodemo/bufferdemo/buffer3.java

@ -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();
}
}

39
src/main/java/com/louzin/niodemo/bufferdemo/buffertest.java

@ -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());
}
}
}

4
src/main/java/com/louzin/niodemo/bufferdemo/test.java

@ -1,4 +0,0 @@
package com.louzin.niodemo.bufferdemo;
public class test {
}

3
src/main/resources/bufferreader.txt

@ -0,0 +1,3 @@
abc
def
hij

3
src/main/resources/copy.txt

@ -0,0 +1,3 @@
abc
def
hij
Loading…
Cancel
Save