java NIO编程(一)

文章参考摘抄自:https://ifeve.com/java-nio-all/

一、java NIO特性:

Channels and Buffers

Channel主要的实现:

  • FileChannel    从文件中读写数据
  • DatagramChannel    通过UDP读写网络中的数据
  • SocketChannel      通过TCP读写网络中的数据
  • ServerSocketChannel  监听新进来的TCP连接,对每一个新进来的连接都会创建一个SocketChannel。

Buffer实现:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

  MappedByteBuffer,用于表示内存映射文件

标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

Non-blocking IO

可以采用多线程从通道读取数据并处理。

Selectors

可以监听多个通道的事件,如连接打开,同时单线程也可监听多个数据通道。要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。

还有Pipe和FileLock

        基本上,所有的 IO 在NIO 中都从一个Channel 开始。Channel 有点象流。 数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。

 

二、文件读写案例:

 

a、通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例

b、从FileChannel中读取数据至Buffer中;返回的int值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾。

c、用完FileChannel后必须将其关闭。

public static  void chanelTest() {
        RandomAccessFile aFile = null;
        try {
            aFile = new RandomAccessFile("D:\\笔记\\dblink.txt", "rw");
            FileChannel inChannel = aFile.getChannel();

            ByteBuffer buf = ByteBuffer.allocate(48);

            int bytesRead = inChannel.read(buf);
            while (bytesRead != -1) {

            System.out.println("Read " + bytesRead);
            buf.flip();

            while(buf.hasRemaining()){
            System.out.print((char) buf.get());

          // channel.write(buf);  //文件写入
            }

            buf.clear();
            bytesRead = inChannel.read(buf);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                aFile.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

 

三、特殊用法

FileChannel的position方法

    在FileChannel的某个特定位置进行数据的读/写操作。也可以通过调用position(long pos)方法设置FileChannel的当前位置。

long pos = channel.position();

channel.position(pos +123);

FileChannel的size方法

返回该实例所关联文件的大小。

long fileSize = channel.size();

FileChannel的truncate方法

截取文件 指定长度并删除其余部分。channel.truncate(1024);

FileChannel的force方法

将通道里尚未写入磁盘的数据强制写到磁盘上。

transferFrom()

FileChannel的transferFrom()方法可以将数据从源通道传输到FileChannel中;position表示从position处开始向目标文件写入数据,count表示最多传输的字节数,如果源通道的剩余空间小于 count 个字节,则所传输的字节数要小于请求的字节数。在SoketChannel的实现中,SocketChannel只会传输此刻准备好的数据(可能不足count字节)。因此,SocketChannel可能不会将请求的所有数据(count个字节)全部传输到FileChannel中。

如:

    RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
    FileChannel      fromChannel = fromFile.getChannel();
    RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
    FileChannel      toChannel = toFile.getChannel();
    long position = 0;
    long count = fromChannel.size();

transferTo()

将数据从FileChannel传输到其他的channel中。

RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel      fromChannel = fromFile.getChannel();

RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
FileChannel      toChannel = toFile.getChannel();
long position = 0;
long count = fromChannel.size();
fromChannel.transferTo(position, count, toChannel);

 

 

附中文乱码处理:

文件读取到后,写入时做编码处理:

  1. Charset charset = Charset.forName("GBK");

  2. CharsetDecoder charDecoder = charset.newDecoder();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值