JAVA篇_IO流

一、认识IO流

咱们目前学习的是BIO,阻塞的IO流,NIO(none-block-I-O)不阻塞的IO。学习IO流的目的是使用它来读写数据或者写数据到文件。

  • BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
  • NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。Netty 服务器底层使用Netty通信 Tomcat 8.x 底层也支持NIO通信。
  • AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它 AIO(Asynchronous IO),异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

1.1 IO流分类

        1:方向:输入流 和 输出流,输入流是指从磁盘或者其他位置读到内存,输出流是指从内存到磁盘等其他位置

        2:内容:字符流 和 字节流

1.2 IO流体系

二、字节流

2.1 文件流

以字节形式读取文件数据,通常适用于读二进制文件 如图片 视频 音频文件等。

2.1.1 输入流 FileInputStream

 System.out.println("-------------文件--------------");
        //1.创建文件 f 给定文件位置
        File file=new File("G:\\javaWorkspeace\\day22\\src\\classExmaple\\FileinputStream\\test.txt");
        //判断文件是否存在
        if (file.exists()){
            System.out.println("该路径是否是文件:"+file.isFile()+" 是不是文件夹:"+file.isDirectory());
            System.out.println("路径:"+ file.getPath()+"  \n绝对路径:"+file.getAbsolutePath());
            System.out.println("最后修改时间:"+file.lastModified()+"  文件大小:"+file.length());
            System.out.println("文件名:"+file.getName());
        }else {
            //新建文件f
            file.createNewFile();
        }
        System.out.println("----------文件输出流-----------");
        //2.文件输出流(内存到磁盘)
        FileOutputStream fos=new FileOutputStream(file);
        String[] masage=new String[]{"你好啊","word","爪洼"};
        for (int i = 0; i < 3; i++) {
            //翔文件里面写内容,由于文件存储的字节类型,所以这里的masage要转换成字节类型再写进去
            fos.write(masage[i].getBytes());
        }
        //关闭流
        fos.close();

2.1.2 输出流 FileOutStream

 //3.文件输入流
        FileInputStream fis=new FileInputStream(file);
        //读数据(磁盘到内存)
        byte [] buff=new byte[6]; //6个长度的byte数组来接受磁盘的内容
        int len=0; //定义一个长度,来表示缓冲区buff里有没有内容,如果没有则为-1,有则为内容的长度
        while ((len=fis.read(buff))!=-1){
            //从buff中读取0到len的内容,变成String类型输出
            System.out.println(new String(buff,0,len));
        }
        //关闭输入流
        fos.close();

2.2 缓存流

没有特别功能,指定提供了缓冲,优先从缓存中读写,降低和IO设备访问次数提高效率。

2.2.1 输入流 BufferedInputStream

    public static void main(String[] args) throws IOException {
        //1. 创建流
        BufferedInputStream bis =
                new BufferedInputStream(
                        new FileInputStream("G:/word.txt"));

        //2. 读文件
        byte[] buff = new byte[1024];
        int len = 0;
        while( (len=bis.read(buff)) !=-1  ){
            String xx = new String( buff, 0 , len );
            System.out.println(xx);
        }
        //3.关闭
        bis.close();
    }

2.2.2 输出流 BufferedOutputStream

  public static void main(String[] args) throws IOException {

        //1. 创建流
        BufferedOutputStream bos =
                new BufferedOutputStream(
                        new FileOutputStream("G:/word.txt")  );
        //2. 写数据
        String massage = "q床前明月光,疑是地上霜q";
        bos.write( massage.getBytes() );
        bos.flush(); //缓冲流的方法
        //3. 关闭流
        bos.close();

    }

2.3 对象流

对象流作用是,可以把一个对象写到文件中,或者把一个文件中的对象,读取到内存。它就是序列化和反序列化的流:

序列化: 把对象二进制信息 写入流。

反序列化: 从流中读取对象的二进制信息,还原到内存。

2.3.1 序列化流ObjectOutputStream

一个类的对象支持序列化,那么这个类型必须实现一个 Serializable 标志接口。

细节: 一个类要可以被序列化,要求其属性也是可序列化的除非显示添加 transient 修饰 ,表示这个属性不参与序列化。静态属性不参与序列化

public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1. 创建流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
        //2. 读,必须按照序列化顺序读取且不可多读,否则引发EOFException异常。
        int num = ois.readInt();
        int num2 = ois.readInt();
        Coder coder = (Coder) ois.readObject();

        System.out.println(num);
        System.out.println(num2);
        System.out.println(coder);

        //3.关闭
        ois.close();

  }

2.3.2 反序列化流ObjectInputStream

public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1. 创建流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
        //2. 读,必须按照序列化顺序读取且不可多读,否则引发EOFException异常。
        int num = ois.readInt();
        int num2 = ois.readInt();
        Coder coder = (Coder) ois.readObject();

        System.out.println(num);
        System.out.println(num2);
        System.out.println(coder);

        //3.关闭
        ois.close();

  }

三.字符流

3.1 文件流[重点]

以子符形式读取文件数据,通常适用于读取纯文本文件 存文本信息。

3.1.1 FileReader 输入流

 public static void main(String[] args) throws IOException {

        //1 创建流
        FileReader reader = new FileReader("node.txt");
        //2 读数据
        char[] buff = new char[1024];
        int len=0;
        while (    (len=reader.read(buff)) !=-1           ){
             String str = new String( buff,0,len );
            System.out.println(str);
        }
        //3 关闭
        reader.close();
    }

3.1.2 FileWriter 输出流

 public static void main(String[] args) throws IOException {

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入标题");
        String title = scanner.next();
        System.out.println("输入内容");
        String content = scanner.next();

        //把数据写到文件中
        //1. 创建
        FileWriter fw = new FileWriter("node.txt",true);
        //2. 写数据
        fw.write(title);
        fw.write("\n------------------------------------------\n");
        fw.write(content);
        fw.write("\n-----------------end----------------------\n");
        //3.关闭
        fw.close();

    }

3.2 缓冲流

3.2.1 BufferedReader 输入流

特别方法 readLine() 可以一次读取一行,如果未读到返回null

public static void main(String[] args) throws IOException {
        //1 创建流
        BufferedReader br = new BufferedReader( new FileReader("g:/book.txt"));
        //2 读数据
        String buff=null;
        while( (buff =br.readLine()) !=null ){
           // System.out.println(buff);
            String[] info = buff.split(",");
            System.out.println(info[0]);
        }
        //3.关闭流
        br.close();
 }

3.2.2 BufferedWriter 输出流

特别方法 newLine() 相当于写一个换行符

public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入标题");
        String title = scanner.next();
        System.out.println("输入内容");
        String content = scanner.next();
        //1.创建流
        BufferedWriter bw = new BufferedWriter(  new FileWriter("node.txt",true));
        //2.写数据
        bw.write( title );
        bw.newLine(); //写一个回车 换行
        bw.write("-------------------------------------");
        bw.newLine();
        bw.write(content);
        bw.newLine();
        bw.write("----------------end--------------------");
        //3.刷新
        bw.flush();
        //4.关闭
        bw.close();
    }

3.3 转换流[重点]

有些时候,如果读取的文件是文本文件,但是提供的却是字节流,字符流明显读取文本字符更加方便,这时可以把字节流转换成字符流操作。

只有字节流转 字符流没有字符流转字节流,转换流本身就是一种字符流。

3.3.1 InputStreamReader 输入流

/**
 * 字节输入流  转 字符输入流
 */
public class InputStreamReaderCase {

    public static void main(String[] args) throws IOException {

        //字符流
        BufferedReader br = new BufferedReader( new InputStreamReader(  new FileInputStream("d:/text.txt")  )  );

        String buff = null;

        while (  (buff=br.readLine()) !=null  ){
            System.out.println(buff);
        }

        br.close();
        
    }
}

3.3.2 OutputStreamWriter 输出流

 *
 *  字节输出流  转 字符输出流
 */
public class OutputStreamWriterCase {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(   new OutputStreamWriter( new FileOutputStream("d:/text.txt")  ) );
        bw.newLine();
        bw.write("王麻子,20,男,C#");
        bw.flush();
        bw.close();
    }
}

3.4 编码与字符集

编码指的是把字符与数字对应的过程。 字符集就是一张记录了对应关系的信息表。ASCII就是一种编码表。像这种还有很多。

  1. GBK 国标码
  2. ISO-8859-1 西欧语言
  1. Big5 台湾香港 繁体字
  2. Unicode 联合编码( UTF-8 UTF-16 )
public static void main(String[] args) throws IOException {

        String hello = "你好中国";
        byte[] bytes = hello.getBytes();// UTF-8  解码
        System.out.println(Arrays.toString(bytes));

        byte[] buff = {-28, -67, -96, -27, -91, -67, -28, -72, -83, -27, -101, -67};
        String newHello = new String( buff ,"UTF-8" ); // 使用 UTF-8 编码
        System.out.println(newHello);

        System.out.println("--------------------------------------");
        FileInputStream fis = new FileInputStream("d:/hello.txt");
        InputStreamReader isr = new InputStreamReader(fis,"GBK");

        char[] buff2= new char[1204];
        int len;
        while (  ( len = isr.read(buff2))!=-1  ){
            System.out.println(buff2);
        }
        isr.close();
        fis.close();
    }

编码解码不一致,就会出现乱码

四.打印流

打印流也是输出流, 存在字节打印流和字符打印流。

字节打印流PrintStream

public class PrintDemo {
    public static void main(String[] args) throws IOException {
        // 直接打印到文件
        PrintStream out = new PrintStream("d:/abc.txt");
        out.println("helloword");

        //  打印到 其他字节输出流
        FileOutputStream os = new FileOutputStream("d:/abc.txt",true);
        PrintStream out2 = new PrintStream( os);
        out2.println("java");
    }
}

字符打印流 PrintWriter

public class PrintDemo {
    public static void main(String[] args) throws IOException {

        //直接 打印到文件
        PrintWriter pw = new PrintWriter("D:/abc.txt");
        pw.println("css");
        pw.close();
        //打印 到其它字符输出流
        PrintWriter pw2 = new PrintWriter(  new FileWriter("d:/abc.txt",true));
        pw2.println("java");
        pw2.close();
        //打印 到其他字节输出流
        PrintWriter pw2 = new PrintWriter(  new FileOutputStream("d:/abc.txt",true)  );
        pw2.println("java");
        pw2.close();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值