栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

NIO 类的基本用法 --《JAVA编程思想》79

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

NIO 类的基本用法 --《JAVA编程思想》79

JDK 1.4 引入了 java.nio.* 新类库提升 I/O 读写速度, 效率的提升主要得益于 nio 类库中采用的数据结构更接近于操作系统执行 I/O 的方式:通道和缓冲器。

通道作为数据仓库,缓冲器作为搬运工,在通道内对数据进行读写操作,我们只操作缓冲器,不直接与通道产生联系。

目录
  • 1.创建通道
  • 2.快速复制
  • 3.编码解码
    • 3.1 编码
    • 3.2 解码
  • 4.获取基本类型

1.创建通道

下面先来看个简单的示例:

FileOutputStream、RandomAccessFile、FileInputStream 分别对应只写通道、读写通道、读通道的获取方式;

FileChannel 中只能写入字节,读取的时候也是如此,无法直接读取字符;

需要注意的是,调用 FileChannel 中的 read() 方法后,必须调用 flip() 方法将 ByteBuffer 中的指针移动至头部(read() 方法调用后,指针会移动至尾部),否则无法读取出数据;

allocate() 用于创建指定大小的缓冲区,单位为字节;

使用通道和缓冲器进行读写的效率会显著高于普通的 I/O 类,感兴趣的朋友可以自行测试;

public class GetChannel {

    public static void main(String[] args) throws IOException {
        //获取通道
        FileChannel fc = new FileOutputStream("D:\test\a.txt").getChannel();
        //缓冲器写入
        fc.write(ByteBuffer.wrap("some txt ".getBytes()));
        fc.close();
        fc = new RandomAccessFile("D:\test\a.txt", "rw").getChannel();
        //指定写入起始位置
        fc.position(fc.size());
        fc.write(ByteBuffer.wrap("some more ".getBytes()));
        fc.close();
        fc = new FileInputStream("D:\test\a.txt").getChannel();
        //创建指定大小的缓冲器
        ByteBuffer buff = ByteBuffer.allocate(1024);
        fc.read(buff);
        //必须执行,将缓冲区的指针移动至头部
        buff.flip();
        //使用迭代器遍历,类似Iterator的hasNext()
        while (buff.hasRemaining()) System.out.print((char) buff.get());
    }
    
}
some txt some more 
2.快速复制

我们可以将一个通道与另外一个通道直接相连,从而达到快速复制的效果,具体操作如下:

    public static void main(String[] args) throws IOException {
        FileChannel in = new FileInputStream("D:\test\a.txt").getChannel(),
                out = new FileOutputStream("D:\test\b.txt").getChannel();
        in.transferTo(0,in.size(),out);
        //第二种方式
        //out.transferFrom(in, 0, in.size());
    }

in.transferTo() 的参数分别为:读取的起始位置、读取的长度、写入的通道;

也可以通过 out.transferFrom() 来实现相同的效果,其对应的参数为:读取的通道、读取的起始位置、读取的长度

3.编码解码

缓冲器内容纳的是普通字节,为了将它们转换成字符,需要在输入它们的时候进行编码,或者输出的时候进行解码,否则读取出来的字符会出现乱码现象;

3.1 编码

通过 ByteBuffer 写入的时候,指定字节数组的编码格式;

  • 示例:
    public static void main(String[] args) throws IOException {
        FileChannel out = new FileOutputStream("D:\test\a.txt").getChannel();
        //指定写入字节的编码格式
        out.write(ByteBuffer.wrap("富强 民主 文明 和谐 自由 平等 公正 法治 爱国 敬业 诚信 友善".getBytes("UTF-16BE")));
        out.close();
        FileChannel in = new FileInputStream("D:\test\a.txt").getChannel();
        ByteBuffer buff = ByteBuffer.allocate(1024);
        in.read(buff);
        buff.flip();
        System.out.println(buff.asCharBuffer());
    }
富强 民主 文明 和谐 自由 平等 公正 法治 爱国 敬业 诚信 友善
3.2 解码

ByteBuffer 读取完成后,通过 Charset 类提供的方法对其进行解码操作;

  • 示例:
    public static void main(String[] args) throws IOException {
        FileChannel out = new FileOutputStream("D:\test\a.txt").getChannel();
        out.write(ByteBuffer.wrap("富强 民主 文明 和谐 自由 平等 公正 法治 爱国 敬业 诚信 友善".getBytes()));
        out.close();
        FileChannel in = new FileInputStream("D:\test\a.txt").getChannel();
        ByteBuffer buff = ByteBuffer.allocate(1024);
        in.read(buff);
        buff.flip();
        //对缓冲器内的文本进行解码
        System.out.println(Charset.forName("UTF-8").decode(buff));
    }
富强 民主 文明 和谐 自由 平等 公正 法治 爱国 敬业 诚信 友善
4.获取基本类型

ByteBuffer 虽然只能保存字节类型的数据,但是它提供读取和写入各种基本类型的方法。

  • 示例:
    ByteBuffer 提供 asCharBuffer()、asShortBuffer()、asIntBuffer() 等获取对应基本类型的视图,然后使用视图的 put() 方法插入数据,值得一提的是:ShortBuffer 的 put() 方法放入超过 short 最大上限的数值时,会进行窄化转换,导致结果会变更。

ByteBuffer.allocate(int capacity) 创建指定大小的缓冲区,并为每个位置的值自动置零,故可以通过判断当前位置是否为零得出其位置上有没有分配内容;

    public static void main(String[] args) throws IOException {
        //分配ByteBuffer的大小
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //获取char类型的视图
        CharBuffer charBuffer = buffer.asCharBuffer();
        charBuffer.put("put char");
        char c;
        while ((c = buffer.getChar()) != 0) {
            System.out.print(c);
        }
        //重置读取位置,从0开始
        buffer.rewind();
        System.out.println();
        //获取short类型的视图
        ShortBuffer shortBuffer = buffer.asShortBuffer();
        short max = Short.MAX_VALUE;
        System.out.println("short max:" + max);
        shortBuffer.put((short) 471124);
        System.out.println(buffer.getShort());
        shortBuffer.put((short) 1234);
        System.out.println(buffer.getShort());
        buffer.rewind();
        //获取int类型的视图
        IntBuffer intBuffer = buffer.asIntBuffer();
        intBuffer.put(99471142);
        System.out.println(buffer.getInt());
        buffer.rewind();
    }
put char
short max:32767
12372
1234
99471142

本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/657609.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号