NIO流

缓冲区

在JDK1.4之后引入了一个NIO,即new IO,NIO和IO有很多得作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。
Java中的NIO主要核心有:缓冲区buffer,通道Channels,选择器Selectors,接下来我会主要写写缓冲区和通道

缓冲区

NIO中的缓冲区就是容器,底层用数组来存的,一旦定义长度之后无法改变
Buffer 下面针对基本数据类型,都有提供相应的子类(boolean)
ByteBuffer 常用的
ShortBuffer
IntBuffer
LongBuffer
CharBuffer
DoubleBuffer
FloatBuffer

ByteBuffer

Buffer 缓冲区中几个重要的属性
capacity; 缓冲区的最大容量
position 读取数据是,具体位置
limit; 界限
mark 书签,标记,可以记录 position 可以通过一个方法,会到我刚才标记的位置
对于ByteBuffer中来说,有俩个方法可以读取和写入数据

 String str = "abcde";
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);首先定义容器长度
        byteBuffer.put(str.getBytes());将字符串改变为字节放入容器中
        byteBuffer.flip();    转换成读取模式
        byte[] bytes = new byte[byteBuffer.limit()];
        byteBuffer.get(bytes, 0, 2);先读一部分
        System.out.println("position:" + byteBuffer.position());
        byteBuffer.mark(); //记录 positon的位置
        byteBuffer.get(bytes, 2, 2);再读一部分
        byteBuffer.reset();//回到上次记录的positonde位置
         byteBuffer.clear();删除缓冲区的数据,起始数据没有被真正的删除,只是处于被遗忘的状态,将position归0
        if (byteBuffer.hasRemaining()) {//判断是否还有剩余数据
            System.out.println(byteBuffer.remaining()); //还剩多少数据
        }

缓冲区分类:(Channel)
非直接缓冲区:将缓冲区建立在JVM的内存中 ByteBuffer.allocate(1024);
直接缓冲区:将缓冲区建立在操作系统的物理内存中,可以提高数据的读写效率 ByteBuffer.allocateDirect(1024);

通道

通道:让源节点和目标节点建立连接,通道本身不存储数据,他跟缓冲区进行交互
Java 为 Channel 接口提供的最主要实现类如下
本地文件传输通道
FileChannel :用于读取、写入、映射和操作文件的通道
网络数据传输的通道
DatagramChannel :通过 UDP 读写网络中的数据通道(UDP是一种无连接的协议,特点是无连接,不存在服务器和客户端,只存在接受者和发送者)
SocketChannel :通过 TCP 读写网络中的数据。()
ServerSocketChannel :可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel

获取通道的几种方式

方式1 通过FileInputStream FileOutputStream RandomAccessFile中的getChannel()方法可以获取通道
方式2 通过 FileChannel 中的 静态方法 open() 可以打开通道
方式3 Files.newByteChannel()
方式4 Channels.newChannel()

方式一

通过 FileInputStream FileOutputStream RandomAccessFile 中的getChannel()方法可以获取通道

 FileInputStream in = new FileInputStream("领悟.mp3");
        FileOutputStream out = new FileOutputStream("领悟2.mp3");
        //获取通道
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        //定义缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //用的是非直接缓冲区
        while (inChannel.read(byteBuffer) != -1) {
            //切换读取模式
            byteBuffer.flip();
            outChannel.write(byteBuffer);
            byteBuffer.clear();//清空缓冲区
        }
        in.close();
        out.close();
        inChannel.close();
        outChannel.close();

获取通道的第二种方式

 public static void main(String[] args) throws IOException {
        FileChannel open = FileChannel.open(Paths.get("C:\\Users\\666\\Desktop\\786.exe"), StandardOpenOption.READ);
        FileChannel open1 = FileChannel.open(Paths.get("C:\\Users\\666\\Desktop\\78.exe"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);//此处设置为可读可写模式
      /*  StandardOpenOption.CREATE 文件不存在,就创建,如果存在,就覆盖
         StandardOpenOption.CREATE_NEW 文件不存在就创建,如果存在,就报错*/
        ByteBuffer buffer = ByteBuffer.allocate(1024);用的是非直接缓冲区
        while (open.read(buffer)!=-1){
           buffer.flip();
           open1.write(buffer);
           buffer.clear();
        }
        open.close();;
        open1.close();

    }




   FileChannel inChannel = FileChannel.open(Paths.get("D:\\IntelliJIDEA2018.2.6.7z"), StandardOpenOption.READ);
        //StandardOpenOption.CREATE 文件不存在,就创建,如果存在,就覆盖
        // StandardOpenOption.CREATE_NEW 文件不存在就创建,如果存在,就报错
        FileChannel outChannel = FileChannel.open(Paths.get("E:\\IntelliJIDEA2018.7z"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
        //建立物理内存映射文件
        MappedByteBuffer inMappedByteBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
        MappedByteBuffer outMappedByteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
        //操作直接缓冲区,进行数据的读写

        byte[] bytes = new byte[inMappedByteBuffer.limit()];
        inMappedByteBuffer.get(bytes);
        outMappedByteBuffer.put(bytes);

        inChannel.close();
        outChannel.close();



FileChannel inChannel = FileChannel.open(Paths.get("test.txt"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("test2.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
        //分散
        //创建两个缓冲区
        ByteBuffer buffer1 = ByteBuffer.allocate(101);
        ByteBuffer buffer2 = ByteBuffer.allocate(100);
        ByteBuffer[] byteBuffers = new ByteBuffer[]{buffer1, buffer2};
        inChannel.read(byteBuffers);
        //切换读取模式
        //byteBuffers[0].flip();
        //byte[] array = byteBuffers[0].array();
        //System.out.println(new String(array, 0, byteBuffers[0].limit()));
        for (ByteBuffer byteBuffer : byteBuffers) {
            byteBuffer.flip();
        }

        outChannel.write(byteBuffers);

获取通道的第三种方式

FileChannel channel = new FileInputStream(“a.txt”).getChannel();
FileChannel.open()
JDK1.7 Files类
SeekableByteChannel seekableByteChannel = Files.newByteChannel(Paths.get(“a.txt”), StandardOpenOption.READ);
Channels.newChannel()
static long copy (InputStream in, Path target, CopyOption…options)
将所有字节从输入流复制到文件。
static long copy (Path source, OutputStream out)
将从文件到输出流的所有字节复制到输出流中。
static Path copy (Path source, Path target, CopyOption…options)
将一个文件复制到目标文件。
Files类里面复制文件的方法
Files.copy(new FileInputStream(“领悟.mp3”),Paths.get(“领悟5.mp3”));
Files.copy(Paths.get(“领悟.mp3”),new FileOutputStream(“领悟6.mp3”));
Files.copy(Paths.get(“E:\疯狂动物城.mp4”),Paths.get(“E:\疯狂动物城aaa.mp4”));

零碎的东西

public static Path write (Path path, Iterable < ? extends CharSequence > lines, Charset cs, OpenOption…options)
写入文本到文件的行。每一行是一个字符序列,写入每条线由平台的行分隔符终止序列文件,由系统定义的属性。
options参数指定如何创建或打开文件。如果没有选择,那么这种方法的工作原理是如果CREATE,TRUNCATE_EXISTING,和WRITE选项出现。换句话说,它打开写文件,如果文件不存在,创建文件,或者最初截断现有regular - file到大小0。该方法确保当所有的行被写入(或一个I / O错误或其他运行时异常被抛出时关闭该文件)。如果一个I / O错误发生,那么它可能会这样做后,该文件已创建或截断,或后,一些字节已写入文件。
参数
path - 文件的路径
lines对象遍历字符序列
cs的字符集进行编码使用
options选项指定如何打开文件
rayList list = new ArrayList<>();
st.add(“asfdasfdasf”);
st.add(“asfdasfdasf”);
st.add(“asfdasfdasf”);
list.add(“你好”);
Files.write(Paths.get(“test444.txt”), list, Charset.forName(“UTF-8”));
将集合里的东西放入test444.txt中

多线程

在多线程里,首先要弄清2个概念,线程和进程,线程依赖于进程,进程指的是一个正在运行的程序,而它当中的各项功能就可以看成是一个个线程。进程是拥有资源的基本单位,线程是CPU调度的基本单位。进程就像是人身体的各个部件,而线程可以看作是其中的神经线,CPU控制神经线。

线程

创建线程的方式1
1.创建一个类,继承Thread
2.重写Thread类中的run方法
3,创建我们写的这个子类对象
4.开启线程,让他执行run方法里面的代码
MyThread myThread2 = new MyThread();
myThread2.start();
然后就是线程的执行,多线程的执行是随机的,线程的命名可以调用setName方法。
线程优先级的设定:
myThread.setPriority(Thread.MIN_PRIORITY);最小是1
myThread2.setPriority(Thread.MAX_PRIORITY);最大时10
优先级的高低仅代表线程被执行的可能性,不是必然。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值