IO流、NIO

IO流:

a、I是指Input(输入),O是指Output(输出)

b、在Java中,文件的输入输出是通过流来实现的,用来实现程序或进程间的通信,或读写外围设备,文件等

c、一个流,必有源端和目的端,它们可以是计算机内存的某区域,也可以是磁盘文件,甚至可以是Internet上的某个URL,对于流而言,我们不用关心数据是如何传输的,只需要向源端输入数据,向目的端获取数据即可。

d、流按照处理数据的单位,可以分为字节流和字符流,按照流向分为输入流和输出流

字节流:用于操作字节为单位的二进制文件文件(音频 视频 图片 docx等,用记事本打开是乱码的文件一般就是字节流)

常用方法:

FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
        //输入流
    fileInputStream = new FileInputStream("C:/Java_Tools/image/hello.jpg");
    //输出流
        fileOutputStream = new FileOutputStream("C:/Java_Tools/hello.jpg");

    byte[] car = new byte[1024];
    int length = 0;

    //当读取数据为-1了,读取结束
    while((length=fileInputStream.read(car))!=-1){
        fileOutputStream.write(car,0,length);
    }

    //冲刷缓存
    fileOutputStream.flush();
} catch (Exception e) {
    e.printStackTrace();
}finally{

    if(fileInputStream!=null){
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    if(fileOutputStream!=null){
        try {
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}    

字符流:将字节转换为2个字节的Unicode字符就有了字符流,用于操作字符文件(记事本等)

常用方法:

FileReader fileReader null;
FileWriter fileWriter = null;
try {
    //输入流
    fileReader = new FileReader("C:/Java_Tools/log.log");
    //输出流
        fileWriter = new FileWriter("C:/Java_Tools/image/log.log");

    char[] car = new char[1024];
    int length = 0;

    while((length=fileReader.read(car))!=-1){
        fileWriter.write(car,0,length);
    }
    fileWriter.flush();

} catch (Exception e) {
    e.printStackTrace();
}finally{

    if(fileReader!=null){
        try {
            fileReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    if(fileWriter!=null){
        try {
            fileWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

缓冲流——数据在复制过程中会从磁盘中获取,有一个缓冲区

缓冲字节流:实现字节为单位的二进制文件

输入流:BufferedInputStream

输出流:BufferedOutputStream

缓冲字符流:实现2个字节的字符文件

输入流:BufferedReader

输出流:BufferedWriter

转换流:由于文件自身编码方式和程序运行时使用的默认编码方式不一致,致使程序读取或输出字符文件时可能会出现乱码,这时可以使用字节流操作文件,然后再讲字节流转换成字符流

字节输入流——>字符输入流:InputStreamReader

字节输出流——>字符输出流:OutputStreamWriter

NIO(NEW IO):

NIO提供多路非阻塞式的高伸缩性网络I/O,从而提高了效率,NIO主要有三大核心组件:Channel、Buffer、Selector,重点介绍前两者

Buffer:Buffer是一个抽象类,Buffer类型变量对应的对象代表一块缓冲区,ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer类都是Buffer抽象类的子类,其中ByteBuffer最常用

常用方法:

a、static ByteBuffer allocate(int capacity):分配一个新的字节缓冲区

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
    }
}

b、int capacity() :返回此缓冲区的容量,实际上直接将capacity成员属性值返回。

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            System.out.println(bytebuffer.capacity());
    }
}
//输出结果:1024

c、ByteBuffer put(byte b):将字节类型数据写入当前位置的缓冲区,然后position+1,位置从0开始

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            byte a=3;
            bytebuffer.put(a);
    }
}

d、byte[] array() :将ByteBuffer类型的数据转为byte数组

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            byte a=3;
            bytebuffer.put(a);
            byte[] bbuf=bytebuffer.array();
    }
}

e、int position():返回缓冲区当前位置,实际上直接将position成员属性值返回。

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            System.out.println(bytebuffer.position());
            byte a=3;
            bytebuffer.put(a);
            System.out.println(bytebuffer.position());
    }
}
//输出结果:0   1

f、Buffer flip() :翻转缓冲区,将当前position值赋值给limit,并将position置零;这个方法主要防止在最后一次输出时,如果缓存区并未装满,则将position值赋值给limit即为当前缓冲区内数据量,一般搭配hasRemaining方法使用。如果没有limit属性而直接使用capacity,则会输出冗余数据。

源码分析:

举例:

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            bytebuffer.position();
            byte a=3;
            bytebuffer.put(a);
            bytebuffer.position();
            bytebuffer. flip();
            bytebuffer.position();
    }
}
//输出结果:0   1   0

g、byte get()读取缓冲区当前位置的字节,然后当前位置+1

public class Test {
    public static void main(String[] args) {
            ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
            bytebuffer.position();
            byte a=3;
            bytebuffer.put(a);
            bytebuffer.position();
            bytebuffer. flip();
            bytebuffer.position();
            bytebuffer.get();
    }
}

h、boolean hasRemaining():在释放缓冲区时告诉您是否已经达到缓冲区的上界

源码分析:

举例:

public class Test {
    public static void main(String[] args) {
        ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
        System.out.println(bytebuffer.position());
        byte a=3;
        bytebuffer.put(a);
        System.out.println(bytebuffer.position());
        System.out.println(bytebuffer.hasRemaining());
        bytebuffer. flip();
        bytebuffer.get();
        System.out.println(bytebuffer.position());
        System.out.println(bytebuffer.hasRemaining());
    }
}
//输出结果:0   1   true   1   false

i、Buffer clear():将缓冲区重置为空状态。它并不改变缓冲区中的任何数据元素,而是仅仅将上界值初始化为容量的值,并把位置设回0。

源码分析:

举例:

public class Test {
    public static void main(String[] args) {
        ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
        bytebuffer.position();
        byte a=3;
        bytebuffer.put(a);
        bytebuffer.clear();
        System.out.println(bytebuffer.get());
        System.out.println(bytebuffer.position());
        System.out.println(bytebuffer.hasRemaining());
    }
}
//输出结果:3   1   true

Channel:一个接口,该接口类型变量指向的对象代表一个数据传输通道,Channel对象是面向缓冲区的:数据总是从通道读取到缓冲区(Buffer类型对象),或从缓冲区(Buffer类型对象)写入到通道中

常用方法:

a、FileChannel:从文件中读写数据。

b、DatagramChannel:通过UDP读写网络中的数据。

c、SocketChannel:通过TCP读写网络中的数据。

d、ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样,对每一个新进来的连接都会创建一个SocketChannel。

public class Test {
    public static void main(String[] args) {
        try {
            FileInputStream fileInputStream=new FileInputStream("C:/Java_Tools/log.log");
            FileChannel inChannel=fileInputStream.getChannel();

            FileOutputStream fileOutputStream=new FileOutputStream("C:/Java_Tools/image/log.log");
            FileChannel ouChannel=fileOutputStream.getChannel();

            ByteBuffer byteBuffer= ByteBuffer.allocate(1024);
            while(inChannel.read(byteBuffer)!=-1) {
                byteBuffer.flip();
                ouChannel.write(byteBuffer);
                byteBuffer.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

原文地址:https://www.cnblogs.com/yimengxianzhi/p/12419523.html

时间: 2024-10-19 15:22:15

IO流、NIO的相关文章

Java IO流-NIO简介

2017-11-05 22:09:04 NIO NIO:new IO就是新IO的意思,JDK4开始出现新IO,新IO和传统的IO有相同的目的,都是用于进行输入输出的,但是新IO使用了不同的方式来处理输入输出,采用内存映射文件的方式,将文件或者文件中的一段区域映射到内存中,就可以相访问内存一样来访问文件了,这种方式的效率比旧IO要高很多,但是目前好多地方我们看到还是旧IO为主. 一个小例子: Path:路径 Paths:有一个静态方法返回一个路径       public static Path

java 21 - 15 新IO流 NIO

1:JDK4  新IO要了解的类 Buffer(缓冲),Channer(通道) 2:JDK7  要了解的新IO类 Path:与平台无关的路径. Paths:包含了返回Path的静态方法. public static Path get(URI uri):根据给定的URI来确定文件路径. Files:操作文件的工具类.提供了大量的方法, 简单了解如下方法 public static long copy(Path source, OutputStream out) :复制文件 public stati

Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

1.操作基本数据类型的流 1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出流写入稍后由数据输入流读取的数据. · DataOutputStream:数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中.然后,应用程序可以使用数据输入流将数据读入. package datastreamdemos; import java.io.*; /** * Created b

Java基础知识强化之IO流笔记71:NIO的(New IO流)介绍

1. NIO的(New IO流)介绍     JDK4出现NIO.新IO和传统的IO有相同的目的,都是用于进行输入输出的,但新IO使用了不同的方式来处理输入输出,采用内存映射文件的方式,将文件或者文件的一段区域映射到内存中,就可以像访问内存一样的来访问文件了,这种方式效率比旧IO要高很多,但是目前好多地方我们看到的还是旧IO的引用,所以我们仍以旧IO为主,知道NIO即可.

IO流与NIO流

(转自CSDN) IO流上:概述.字符流.缓冲区(java基础) 一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数据传输,Java对于数据的操作都是通过流实现,而java用于操作流的对象都在IO包中. 分类: 按操作数据分为:字节流和字符流. 如:Reader和InpurStream 按流向分:输入流和输出流.如:InputStream和OutputStream IO流常用的基类: * InputStream    ,    OutputSt

面试官:谈谈你对IO流和NIO的理解

一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO. 二.NIO和IO的主要区别 下表总结了Java IO和NIO之间的主要区别: 1.面向流与面向缓冲 Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字

Java IO流 探险

Java的IO流使用了一种装饰器设计模式,它将IO流分为底层节点流和上层处理流.本篇重点在如何访问文件与目录.如何以二进制格式和文本格式来读写数据.对象序列化机制.还有Java7的"NIO.2". 装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能.那么自定义的该类称为装饰类. 装饰类通常会通过构造方法接收被装饰的对象.并基于被装饰的对象的功能,提供更强的功能. IO的方式通常分为:BIO(同步阻塞).NIO(同步非阻塞).AIO

Java IO流详解

初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见. 首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!) 这是java io 比较基本的一些处理流,除此之外我们还会提到一些比较深入的基于io的处理类,比如console类,SteamTokenzier,Externalizable接口,Serializa

IO流(四):其他流

一.操作基本数据类型的流 (一)构造方法 1.数据输入流:DataInputStream(InputStream in) 2.数据输出流:DataOutputStream(OutputStream out) (二)方法 1.DataOutputStream: writeByte(10); writeShort(100); writeInt(1000); writeLong(10000); writeFloat(12.34F); writeDouble(12.56); writeChar('a')