ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

nio初认识之channel

2021-11-28 19:03:09  阅读:137  来源: 互联网

标签:1024 String inputBuffer 认识 System FileChannel new channel nio


一.bio与nio区别

IONIO
面向流(Stream Orientend) 面向缓冲区(Buffer Orientend)
阻塞IO(Blocking IO ) 非阻塞IO(Non Blocking IO)
  选择器(Selector)

 

二.通道(Channel )
  通道表示打开到 IO 设备(例如:文件、套接字)的连接。若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。
  Channel相比IO中的Stream更加高效,可以异步双向传输,但是必须和buffer一起使用。

三.Channel主要实现类
FileChannel,读写文件中的数据。
SocketChannel,通过TCP读写网络中的数据。
ServerSockectChannel,监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
DatagramChannel,通过UDP读写网络中的数据。

四.Channel主要获取方式
  1、java针对支持通道的类提供了getChannel()方法

本地io:
   FileInputStreanm/FileOutputStream
  RandomAccessFile
网络io:
  Socket
  ServerSocket
  DatagramSocket

五.代码实例

package com.tcc.test.nio.channel;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Copyright (C) @2021
 *
 * @author: tcc
 * @version: 1.0
 * @date: 2021/11/28
 * @time: 17:37
 * @description:
 */
public class channeltest {

    //文件复制
    @Test
    public void test() throws Exception {
        FileInputStream fis = new FileInputStream("D:\\1.jpg");
        FileOutputStream fos = new FileOutputStream("D:\\2.jpg");
        //获取通道
        FileChannel inChannel = fis.getChannel();
        FileChannel outChannel = fos.getChannel();
        //分配指定大小缓存区
        ByteBuffer buff = ByteBuffer.allocate(1024);// position 0 ,limit 1024
        //将通道的数据存入缓存区
        while (inChannel.read(buff) != -1) {// position 1024 ,limit 1024 ,相当于put
            //切换读模式
            buff.flip();//position 0 ,limit 1024
            //将缓存去的数据写入通道
            outChannel.write(buff);//position 1024 ,limit 1024,相当于get
            //清空缓冲区
            buff.clear();//position 0 ,limit 1024
        }
        outChannel.close();
        inChannel.close();
        fis.close();
        fos.close();
    }

    //一个文件读其中一部分
    @Test
    public void test2() throws IOException {
        String fff = "D:\\test.txt";
        final int BUFFER_SIZE = 0x300000;// 缓冲区大小为3M

        File f = new File(fff);

        /**
         *
         * map(FileChannel.MapMode mode,long position, long size)
         *
         * mode - 根据是按只读、读取/写入或专用(写入时拷贝)来映射文件,分别为 FileChannel.MapMode 类中所定义的
         * READ_ONLY、READ_WRITE 或 PRIVATE 之一
         *
         * position - 文件中的位置,映射区域从此位置开始;必须为非负数
         *
         * size - 要映射的区域大小;必须为非负数且不大于 Integer.MAX_VALUE
         *
         * 所以若想读取文件后半部分内容,如例子所写;若想读取文本后1/8内容,需要这样写map(FileChannel.MapMode.READ_ONLY,
         * f.length()*7/8,f.length()/8)
         *
         * 想读取文件所有内容,需要这样写map(FileChannel.MapMode.READ_ONLY, 0,f.length())
         *
         */

        MappedByteBuffer inputBuffer = new RandomAccessFile(f, "r")
                .getChannel().map(FileChannel.MapMode.READ_ONLY,
                        f.length() / 2, f.length() / 2);

        byte[] dst = new byte[BUFFER_SIZE];// 每次读出3M的内容

        long start = System.currentTimeMillis();

        for (int offset = 0; offset < inputBuffer.capacity(); offset += BUFFER_SIZE) {

            if (inputBuffer.capacity() - offset >= BUFFER_SIZE) {

                for (int i = 0; i < BUFFER_SIZE; i++)

                    dst[i] = inputBuffer.get(offset + i);

            } else {

                for (int i = 0; i < inputBuffer.capacity() - offset; i++)

                    dst[i] = inputBuffer.get(offset + i);

            }

            int length = (inputBuffer.capacity() % BUFFER_SIZE == 0) ? BUFFER_SIZE
                    : inputBuffer.capacity() % BUFFER_SIZE;

            System.out.println(new String(dst, 0, length));// new
            // String(dst,0,length)这样可以取出缓存保存的字符串,可以对其进行操作

        }

        long end = System.currentTimeMillis();

        System.out.println("读取文件文件一半内容花费:" + (end - start) + "毫秒");
    }

    //全部一次性读
    @Test
    public void test3() throws IOException {
        String fff = "D:\\test.txt";
        int bufSize = 1024;
        byte[] bs = new byte[bufSize];
        ByteBuffer byteBuf = ByteBuffer.allocate(1024);
        FileChannel channel = new RandomAccessFile(fff, "r").getChannel();
        while (channel.read(byteBuf) != -1) {
            int size = byteBuf.position();
            byteBuf.rewind();
            byteBuf.get(bs); // 把文件当字符串处理,直接打印做为一个例子。
            System.out.print(new String(bs, 0, size));
            byteBuf.clear();
        }

    }

    //一行行读
    @Test
    public void test4() throws IOException {
        String fff = "D:\\test.txt";
        BufferedReader br = new BufferedReader(new FileReader(fff));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }


    //每次读取几行
    @Test
    public void test5() throws IOException {
        String path = "D:\\test.txt";
        RandomAccessFile br = new RandomAccessFile(path, "rw");//这里rw看你了。要是之都就只写r
        String str = null, app = null;
        int i = 0;
        while ((str = br.readLine()) != null) {
            i++;
            app = app + str;
            System.out.println("app=="+app);
            if (i >= 2) {//假设读取100行
                i = 0;
// 这里你先对这100行操作,然后继续读
                System.out.println("app22"+app);
                app = null;
            }
        }
        br.close();
    }


    //BufferedReader类读写超大文件,一行行读
    @Test
    public void test6() throws IOException {
        String filepath = "D:\\test.txt";
        File file = new File(filepath);
        BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
        BufferedReader reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),5*1024*1024);// 用5M的缓冲读取文本文件

        String line = "";
        while((line = reader.readLine()) != null){
            System.out.println("line==="+line);
        //TODO: write your business
        }
    }

}

 

标签:1024,String,inputBuffer,认识,System,FileChannel,new,channel,nio
来源: https://www.cnblogs.com/tongcc/p/15616159.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有