byteBuffer_bytebuffer.wrap

byteBuffer_bytebuffer.wrap引言在nio中,流的读取和写入都是依赖buffer的。jdk在nio包中提供了ByteBuffer、CharBuffer、ShortBuffer、LongBuffer、DoubleBuffer、FloatBuffer等。6中类型的buffer还分为两种实现,缓存在jvm堆中和缓存在直接内存中。Buffer主要属性//Invariants:mark<=position&lt…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

引言

在nio中,流的读取和写入都是依赖buffer的。jdk在nio包中提供了ByteBuffer、CharBuffer、ShortBuffer、LongBuffer、DoubleBuffer、FloatBuffer等。 6中类型的buffer还分为两种实现,缓存在jvm堆中和缓存在直接内存中。

Buffer

主要属性

// Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

    // Used only by direct buffers
    // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
    long address;

主要方法

这些方法是用来控制buffer的读写。
jdk提供的buffer只有一个position指针,读和写都是从position的位置开始操作。
代码的流程常常是这样的:
buffer.put(1);
buffer.flip();
buffer.get();
用于多次读取操作

public final Buffer mark() { 
   
        mark = position;
        return this;
    }

public final Buffer reset() { 
   
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }

假装清空

public final Buffer clear() { 
   
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }

翻转指针

public final Buffer flip() { 
   
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

剩余容量

public final int remaining() { 
   
        return limit - position;
    }

获取读写指针的方法

final int nextGetIndex() { 
                             // package-private
        if (position >= limit)
            throw new BufferUnderflowException();
        return position++;
    }

final int nextPutIndex() { 
                             // package-private
        if (position >= limit)
            throw new BufferOverflowException();
        return position++;
    }

ByteBuffer

主要属性

// byte数组
final byte[] hb;                  // Non-null only for heap buffers
// offset 在派生的时候有用
    final int offset;

实例化方法

创建指定容量的heapBuffer和directBuffer

public static ByteBuffer allocate(int capacity) { 
   
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapByteBuffer(capacity, capacity);
    }

public static ByteBuffer allocateDirect(int capacity) { 
   
        return new DirectByteBuffer(capacity);
    }

通过数组创建ByteBuffer

public static ByteBuffer wrap(byte[] array,
                                    int offset, int length)
    { 
   
        try { 
   
            return new HeapByteBuffer(array, offset, length);
        } catch (IllegalArgumentException x) { 
   
            throw new IndexOutOfBoundsException();
        }
    }

put和get方法

public ByteBuffer put(byte x) { 
   
		
		// 获取put的指针 
        hb[ix(nextPutIndex())] = x;
        return this;
    }

public byte get() { 
   
		// 获取get的指针
        return hb[ix(nextGetIndex())];
    }

protected int ix(int i) { 
   
        return i + offset;
    }

派生ByteBuffer
slice创建的Buffer,读写都是在数组的子序列上进行。依赖于Buffer的当前索引

// 共享数组,position=0 mark=-1 limit=cap,
public ByteBuffer slice() { 
   
        return new HeapByteBuffer(hb,
                                        -1,
                                        0,
                                        this.remaining(),
                                        this.remaining(),
                                        this.position() + offset);
    }

复制一个对象,共享数组,拥有相同数值的mark、position、limit、capacity和offset

public ByteBuffer duplicate() { 
   
        return new HeapByteBuffer(hb,
                                        this.markValue(),
                                        this.position(),
                                        this.limit(),
                                        this.capacity(),
                                        offset);
    }

把已经在本buffer写的元素移动到0位置,position定位到剩余容量起点,limit限制为capacity

public ByteBuffer compact() { 
   
        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
        position(remaining());
        limit(capacity());
        discardMark();
        return this;
    }

常用代码段

// 拷贝文件
public void copyFile(String copyFrom,String copyTo){ 
   
	File file = new File(copyFrom);
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
        FileChannel channel = randomAccessFile.getChannel();

        File outFile = new File(copyTo);
        RandomAccessFile outRAF = new RandomAccessFile(outFile, "rw");
        FileChannel outChannel = outRAF.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        while (channel.read(byteBuffer) > 0){ 
   
            while (byteBuffer.hasRemaining()){ 
   
                byteBuffer.flip();
                outChannel.write(byteBuffer);
            }
        }
}

// 从网络中读取文件
public void readNetworkFile(){ 
   
		File outFile = new File("d://20200418220925641.png");
        RandomAccessFile outRAF = new RandomAccessFile(outFile, "rw");
        FileChannel outChannel = outRAF.getChannel();
        // get stream from net
        InputStream inputStream = new URL("https://img-blog.csdnimg.cn/20200418220925641.png").openConnection()
            .getInputStream();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        byte[] cache = new byte[2 * 1024];
        ByteBuffer wrap = ByteBuffer.wrap(cache);
        int len;
        while ((len = bufferedInputStream.read(cache)) > 0){ 
   
            wrap.position(0);
            wrap.limit(len);
            outChannel.write(wrap);
        }
}

public void writeMsgToClient(){ 
   
		ServerSocket serverSocket = new ServerSocket(9988);
		// bad case
        Socket accept = serverSocket.accept();
        SocketChannel channel = accept.getChannel();
        // do business logic and get a byte array
        byte[] rlt = "businessLogicRlt".getBytes();
        ByteBuffer wrap = ByteBuffer.wrap(rlt, 0, rlt.length);
        channel.write(wrap);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/186804.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • loadrunner11基础使用「建议收藏」

    loadrunner11基础使用「建议收藏」装好Loadrunner后要用管理员权限打开,不然可能会报错win10可以装lr12和12.5,但是无法激活成功教程,最大并发50人,还只有7天试用期,7天过了要重新装loadrunner11中主要就是三个模块:VuGen:创建/编辑脚本,脚本录制和脚本增强Controller:运行负载测试,性能场景的设计和性能指标的分析及指标监控Analysis:分析测试结果,性能结果分析,出报告VuGen:创建/编辑脚本主要就是页面中四个按钮,主要用前两个按钮,新建脚本和打开现有脚本。点击新建脚本,选择Web

    2022年10月9日
    0
  • WPF WrapPanel:自动折行面板「建议收藏」

    WPF WrapPanel:自动折行面板「建议收藏」WrapPanel:自动折行面板。内部元素在排满一行后能够自动折行,类似于Html中的流式布局WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够时就会自动调整进行换行,后续排序按照从上至下或从右至左的顺序进行。常用的方法:1.Orientation——根据内容自动换行。当Orientation属性的值设置为Horizontal:元素是从左向右排列…

    2022年7月22日
    6
  • 小旋风asp服务器出错_小旋风服务器用来干什么的

    小旋风asp服务器出错_小旋风服务器用来干什么的 点击是出现下列的对话框:可能是因为因为开着迅雷,因为迅雷是用的80号端口,可以关了迅雷试试,

    2022年10月24日
    0
  • Java设计模式之行为型:访问者模式

    Java设计模式之行为型:访问者模式

    2021年10月4日
    35
  • 谷歌地球手机版2021登不上服务器_谷歌地球连不上服务器是怎么回事

    谷歌地球手机版2021登不上服务器_谷歌地球连不上服务器是怎么回事1、安装运行谷歌地球专业版(GoogleEarthProv7.3)。2、安装运行国家法律允许使用的VPN软件。3、首次运行谷歌地球,需要点击“文件一登录服务器”,如果软件界面显示黑屏。4、选择“帮助一启动修复工具”。5、先关闭谷歌地球软件,保留“修复Google地球界面”不要关闭。6、选择“恢复默认设置”,窗口不要关闭。7、在次运行谷歌地球软件,点击“文件一一登录服务器”,稍等几秒钟熟悉的地球界面出来后,谷歌地球软件即可正常使用。如果谷歌地球软件无法运行,请在wi

    2022年9月19日
    0
  • nextline函数_Java中的nextline()函数与next()问题

    nextline函数_Java中的nextline()函数与next()问题【写在前面】importJava.util.*;Scannerin=newScanner(http://System.in);【出现的问题】在循环中相连的nextLine();会出现第一个nextLine();跳过的问题.就像这个样子://部分代码for(inti=0;iSystem.out.println();Stringname=in.nextLine();System.o…

    2022年6月6日
    28

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号