有关Android NIO我们主要分为三大类,ByteBuffer、FileChannel和SocketChannel。由于篇幅原因今天Android123只对前两个做说明。NIO和传统的I/O比较大的区别在于传输方式非阻塞,一种基于事件驱动的模式,将会使方法执行完后立即返回,传统I/O主要使用了流Stream的方式,而在New I/O中,使用了字节缓存ByteBuffer来承载数据。

ByteBuffer位于java.nio包中,目前提供了Java基本类型中除Boolean外其他类型的缓冲类型,比如ByteBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer  。同时还提供了一种更特殊的映射字节缓冲类型MappedByteBuffer。在传统IO的输入输出流中,InputStream中只提供了字节型或字节数组的访问对应NIO就是ByteBuffer,但是处理传统的DataInputStream的int等类型,就是IntBuffer,但是缓冲类型并没有提供UTF这样的类型处理,所以我们仍然需要使用ByteBuffer处理字符串,但是NIO提供了一个封装的类在java.nio.charset包中,通过字符的编码CharsetEncoder和解码CharsetDecoder类来处理字符串,同时这些类可以方便转换编码比如GBK或UTF等等。

一、ByteBuffer类

1) 实例化

直接使用ByteBuffer类的静态方法static ByteBuffer allocate(int capacity) 或 static ByteBuffer allocateDirect(int capacity)  这两个方法来分配内存空间,两种方法的区别主要是后者更适用于繁复分配的字节数组。而 put(ByteBuffer src) 可以从另一个ByteBuffer中构造,也可以通过wrap方法从byte[]中构造,具体参考下面的类型转化内容。

2) 类型转化

ByteBuffer可以很好的和字节数组byte[]转换类型,通过执行ByteBuffer类的final byte[]  array() 方法就可以将ByteBuffer转为byte[]。从byte[]来构造ByteBuffer可以使用wrap方法,目前Android或者说Java提供了两种重写方法,比如为static ByteBuffer  wrap(byte[] array)  和static ByteBuffer  wrap(byte[] array, int start, int len)  ,第二个重载方法中第二个参数为从array这个字节数组的起初位置,第三个参数为array这个字节数组的长度。

3) 往ByteBuffer中添加元素

目前ByteBuffer提供了多种put重写类型来添加,比如put(byte b) 、putChar(char value) 、putFloat(float value) 等等,需要注意的是,按照Java的类型长度,一个byte占1字节,一个char类型是2字节,一个float或int是4字节,一个long则为8字节,和传统的C++有些区别。所以内部的相关位置也会发生变化,同时每种方法还提供了定位的方法比如ByteBuffer  put(int index, byte b)

4) 从ByteBuffer中获取元素

同上面的添加想法,各种put被换成了get,比如byte  get()  、float  getFloat()  ,当然了还提供了一种定位的方式,比如double  getDouble(int index)

5) ByteBuffer中字节顺序

对于Java来说默认使用了BIG_ENDIAN方式存储,和C正好相反的,通过

final ByteOrder  order() 返回当前的字节顺序。

final ByteBuffer  order(ByteOrder byteOrder)  设置字节顺序,ByteOrder类的值有两个定义,比如LITTLE_ENDIAN、BIG_ENDIAN,如果使用当前平台则为ByteOrder.nativeOrder()在Android中则为 BIG_ENDIAN,当然如果设置为order(null) 则使用LITTLE_ENDIAN。

二、FileChannel类

在NIO中除了Socket外,还提供了File设备的通道类,FileChannel位于java.nio.channels.FileChannel包中,在Android SDK文档中我们可以方便的找到,对于文件复制我们可以使用ByteBuffer方式作为缓冲,比如

String infile = "/sdcard/cwj.dat";
  String outfile = "/sdcard/android123-test.dat";

FileInputStream fin = new FileInputStream( infile );
    FileOutputStream fout = new FileOutputStream( outfile );

FileChannel fcin = fin.getChannel();
    FileChannel fcout = fout.getChannel();

ByteBuffer buffer = ByteBuffer.allocate( 1024 ); //分配1KB作为缓冲区

while (true) {
    buffer.clear(); //每次使用必须置空缓冲区

int r = fcin.read( buffer );

if (r==-1) {
        break;
      }

buffer.flip(); //写入前使用flip这个方法

fcout.write( buffer );
    }

flip和clear这两个方法是java.nio.Buffer包中,ByteBuffer的父类是从Buffer类继承而来的,这点Android123要提醒大家看Android SDK文档时注意Inherited Methods,而JDK的文档就比较直接了,同时复制文件使用FileChannel的transferTo(long position, long count, WritableByteChannel target) 这个方法可以快速的复制文件,无需自己管理ByteBuffer缓冲区。明天Android开发网介绍NIO主要的Socket相关的内容。

android nio的更多相关文章

  1. Android NIO(Noblocking I/O非阻塞I/O)小结

    参考:http://www.cnblogs.com/cpcpc/archive/2011/06/27/2123009.html 对于Android的网络通讯性能的提高,我们可以使用Java上高性能的N ...

  2. Eclipse下Android开发错误之Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace

    升级了Android版本后,在运行应用时提示: [2013-11-27 10:37:35 - Dex Loader] Unable to execute dex: java.nio.BufferOve ...

  3. 【原创】NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战

    概述 本文演示的是一个Android客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo. 当前由于NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能. ...

  4. Java基础知识强化之网络编程笔记24:Android网络通信之 AndroidAsync(基于nio的异步通信库)

    1. AndroidAsync   AndroidAsync 是一个基于nio的异步socket ,http(客户端服务器端),websocket,socket.io库,AndroidAsync 是一 ...

  5. Android集成Mina NIO Socket

    Mina简介 Apache MINA(Multipurpose Infrastructure 多功能框架 for Network Applications) 是 Apache 组织一个较新的项目,它为 ...

  6. android netty5.0 编译时 java.lang.NoClassDefFoundError: io.netty.channel.nio.NioEventLoopGroup

    android netty5.0 编译时 java.lang.NoClassDefFoundError: io.netty.channel.nio.NioEventLoopGroup 复制netty包 ...

  7. android升级后错误:Unable to execute dex: java.nio.BufferOverflowException.Check

    Android SDK Tools升级为22.3,Android SDK Platform-tools 升级为19后,编译工程出现错误: Unable to execute dex: java.nio ...

  8. Android 报错:Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.

    在android高版本开发环境(sdk 4.4)导入低版本(sdk 3.0)的工程时编译报错,报错信息如:Conversion to Dalvik format failed: Unable to e ...

  9. Android raw to bmp

    Android raw 格式转 bmp 图像 raw 保存的为裸数据,转换时都需要把它转成RGBA 的方式来显示.其中: 8位RAW: 四位RGBA 来表示一位灰度; 24位RAW: 三位RGB相同, ...

随机推荐

  1. 8.openssl req

    数字证书申请和生成工具.也可以为根CA自行签署证书. 该命令中很多值.属性.格式或默认值都在config文件openssl.cnf中指定. [root@xuexi ~]# man req NAME r ...

  2. python 获取一个列表有多少连续列表

    python 获取一个列表有多少连续列表 例如 有列表 [1,2,3] 那么连续列表就是 [1,2],[2,3],[1,2,3] 程序实现如下: 运行结果:

  3. jsPlumb的简单使用

    jsPlumb概述jsPlumb是一个在dom元素之间绘制连接线的javascript框架,它使用svg技术绘制连接线. 基本概念很明显,一个连线主要要解决的问题包括谁和谁连,在哪里连(连接点在哪里) ...

  4. 利用Aspose.Pdf将扫描的电子书修改为适合在kindle上查看

    很多扫描版的电子书,留有很大的页边距,大屏的设备看起来没有啥影响,可是在kindle上看起来就麻烦了,放大操作简直就没法用,最好能把留白去掉. 将pdf文件转换为图片这个看看 例子里的 JpegDev ...

  5. c#轻松实现磁性窗口

    /// <summary>/// 磁性窗体函数/// </summary>/// <param name="form">窗体控件(一般传this ...

  6. socket选项总结(setsocketopt)

    功能描述:        获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项, ...

  7. Struts2 的 值栈和ActionContext

    1.ValueStack 和 ActionContext 的关系与区别: -- 相同点:它们都是在一次HTTP请求的范围内使用的,它们的生命周期都是一次请求 -- 不同点:ValueStack 分为对 ...

  8. UML类图画法及其之间的几种关系(转)

    UML类图画法及其之间的几种关系 最近做重构项目,需要画一下类图,发现类图的画法及其之间的几种关系已经淡忘了很多,所以整理总结一下,有问题的地方大家可以一起讨论下. 文章目录如下: 类图画法 类之间的 ...

  9. mongodb的linux环境搭建

    一.启动 [mongodb@node1 ~]$ mongod -f /data/config/shard1.confmongod: /usr/lib64/libcrypto.so.10: no ver ...

  10. 解决:NoSuchAlgorithmException: Algorithm HmacSHA1 not available

    windows下运行macInstance = Mac.getInstance("HmacSHA1");完全正常,Linux下则出现异常: java.security.NoSuch ...