Day19-1.IO流概述 、字节流

1 IO概述

  1. 概述:IO是Input和Output的缩写。
    输入、输出。数据的输入和数据的输出。
  2. 输入输出的概念:
    数据的输入和输出相对于运行内存来说,数据从其他设备进入到运行内存就是输入,数 据从运行内存到其他设备就是输出。
    在这里插入图片描述
    注意:
    IO不是一个类型,而是描述数据输出和输入的概念。
    凡是操作数据输入和输出的类型,都属于IO
  3. 分类:
    按照功能分类:
    字节流:控制字节信息输入和输出
    字符流:控制字符信息的输入和输出
    按照流向分类:
    输入流:控制信息从其他设备到运行内存
    输出流:控制信息从运行内存到其他设备
  4. 具体分类:
    字节输入流:InputStream
    字节输出流:OutputStream
    字符输入流:Reader 读者
    字符输出流:Writer 作者 写者

2 字节流

  1. 概述:用来操作字节信息输入内存和输出内存
  2. 字节输入流InputStream 字节输出流OutputStream

2.1 InputStream

  1. 概述:字节输入流,本类是一个抽象类,不能直接创建对象,需要通过子类创建

  2. 方法:
    read() :

    从流中读取一个字节信息,将读取的信息进行返回。读取的是一个字节,接 收的是一个int。因为读取一个字节之后,在这个字节前面强制加上24个0,强制变为一个int数
    目的:如果不转为int,读取了-1,可能是到达文件末尾,也可能是读取的字节,无法区分,所以为了区分-1是到达文件末尾,就将读取的字节强制变为了int(正数),下次读取到-1之后,表示的肯定是到达文件末尾了。

    read(byte[] b) :

    从流对象中一次读取b.length个字节
    将读取的信息保存在数组中,返回的是读取的个数

    read(byte[] b, int off, int len) :

    从流中读取指定长度的数据到数组中
    将读取的信息保存在数组中,返回的是读取的个数

    available() :

    将流中还没有读取的字节个数进行返回

    close() :

    关闭流资源

2.2 FileInputStream

  1. 概述:属于字节输入流的子类,该类的对象可以将磁盘上的文件数据读取到运行内存中
  2. 构造方法:
    (1)FileInputStream(File file):将file文件对象封装为文件字节输入流对象
    (2)FileInputStream(String str) :将str字符串所描述的文件封装为字节输入流对象
  3. 注意事项:
    在创建对象时,传入的file对象和字符串,对应的必须是一个文件,不能是一个文件夹。

代码

package dems2_in_out;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) throws IOException {
//        FileInputStream fis2 = new FileInputStream(new File("day19/src/a.txt"));
        FileInputStream fis = new FileInputStream("day19/src/a.txt");
        byte[] bs = new byte[10];
        //将读取的字节保存在数组中
        //可以决定从数组的哪一个位置开始保存
        //可以决定读取几个字节
        int len = fis.read(bs, 2, 3);
        System.out.println(len);
        System.out.println(Arrays.toString(bs));
    }
    private static void read2(FileInputStream fis) throws IOException {
        byte[] bs = new byte[10];
        //返回的是读取的字节个数
        //将读取的字节,保存在一个数组中
        int len = fis.read(bs);
        System.out.println(Arrays.toString(bs));
        System.out.println(len);
    }
    private static void read1(FileInputStream fis) throws IOException {
        //一次读取一个字节,将读取的字节返回  如果到达文件末尾返回-1
        System.out.println((char) fis.read());
        System.out.println((char) fis.read());
        System.out.println((char) fis.read());
        System.out.println((char) fis.read());
        System.out.println(fis.read());
    }
}

package dems2_in_out;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

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

        FileInputStream fis = new FileInputStream("day19/src/a.txt");
        //使用循环读取文件中的所有字节
        //如果读取的字节为-1,表示到达末尾,不再读取,如果不是-1,表示读取到了数据,就打印
        int i;
        while((i = fis.read()) != -1){
            System.out.println((char)i);
        }
        //返回文件中剩余的字节个数
        System.out.println(fis.available());
        //关闭流资源
        fis.close();
    }
}

2.3 OutPutStream

  1. 概述:字节输出流,将字节信息从内存中写出到其他设备。也是一个抽象类,需要通过 子类创建对象。
  2. 方法:
函数解释
write(int b)将一个字节信息写出内存
write(byte[] b)将一个数组中的信息写出内存
write(byte[] b, int off, int len)将数组中的一部分信息写出内容
close()关闭流资源

2.4 FileOutputStream

  1. 概述:文件字节输出流,将字节信息从内存中写出到目标磁盘文件中。
  2. 构造方法:
函数解释
FileOutputStream(File file)将file对象封装为一个字节输出流对象
FileOutputStream(String name)将name字符串对应的文件封装为字节输出流对象
FileOutputStream((File file,boolean b)将name字符串对应的文件封装为字节输出流对 象,如果后面的值为false,表示替换写入信息
FileOutputStream(String name,boolean b)将name字符串对应的文件封装为字节输出 流对象,如果后面的值为true,表示追加写入信息

代码

package dems2_in_out;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo03 {
    public static void main(String[] args) throws IOException {
        //创建一个文件字节输出流对象
        FileOutputStream fos = new FileOutputStream("day19/src/b.txt");
        //写出一个字节
        fos.write(97);
        fos.write('b');
        byte[] bs = {99,100,101};
        //将数组中的字节全部写出
        fos.write(bs);
        byte[] bs2 = {'f','g','k','n'};
        //将数组中的一部分字节写出
        fos.write(bs2,2,2);
        fos.close();
    }
}

2.5 文件的拷贝

  1. 概述:将一个文件进行复制

  2. 思路:
    先利用字节输入流读取源文件中的信息,读取之后,再利用字节输出流将读取的信息写 出到另一个文件中。

  3. 图示:
    在这里插入图片描述

  4. 使用字节流拷贝文件,可以拷贝任何类型的文件(图片,视频,音频,只要是一个文件底层都是通过字节来存储的。)

代码

package dems2_in_out;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo05 {
    public static void main(String[] args) throws IOException {
        //创建一个字节输入流
        FileInputStream fis = new FileInputStream("day19/src/a.txt");
        //创建一个字节输出流
        FileOutputStream fos = new FileOutputStream("day19/src/acopy.txt");
        int i;
        //使用循环读取源文件字节
        while((i = fis.read()) != -1){
            //将读取的字节写出到另一个文件
            fos.write(i);
        }
        //关流
        fis.close();
        fos.close();
    }
}

2.6 文件拷贝效率的提升

  1. 问题:
    使用字节输入流和输出流可以完成文件的拷贝,如果文件过大,导致拷贝的速度比较慢。
    如果使用正常方式拷贝,一个字节需要IO两次。
  2. 解决方案1:
    可以一次多读几个字节,一次多写出几个字节
    read(byte[] bs) wirte(byte[] bs);
    使用数组拷贝有一个问题:
    数组在运行内存中开辟空间的,如果数组的空间开辟过大,运行内存的空间就会被 占用太多,就导致整个计算机执行效率下降。
  3. 解决方案2:
    使用小数组拷贝
    使用小数组拷贝注意:
    当前这一次读几个直接,就应该写出几个字节,避免多写出数据
    read(byte[] bs) write(byte[] bs,int off,int len)
    数组大小最好保持在:1024的整数倍即可 1024*8

代码

package dems2_in_out;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo06 {
    public static void main(String[] args) throws IOException {
        test01();
    }
    //使用小数组拷贝:提升拷贝的效率
    private static void test01() throws IOException {
        //创建一个字节输入流
        FileInputStream fis = new FileInputStream("E:\\01_0803就业班\\day18\\06.LinekHashMap特点.mp4");
        //创建一个字节输出流
        FileOutputStream fos = new FileOutputStream("E:\\01_0803就业班\\day18\\06.LinekHashMap特点2222.mp4");

        byte[] bs = new byte[1024*8];
        int len;
         while((len = fis.read(bs)) != -1){
            fos.write(bs,0,len);
         }
        fis.close();
        fos.close();
    }
}

2.7 高效缓冲字节流

  1. 高效缓冲字节输入流:BufferedInputStream
  2. 高效缓冲字节输出流:BufferedOutPutStream
  3. 概述:这两个类型是包装类型,本类的对象不能读取和写出数据,但是这两个类型可以 对基础的流对象进行加强(包装),加强之后,可以默认一次读取多个数据,写出多个 数据,因为这两个类型中都维护了一个数组,来完成文件的拷贝。
  4. 构造方法:
    BufferedInputStream(InputStream in):将基础的字节输入流对象进行包装成为一个高效 字节输入流
    BufferedOutputStream(OutputStream out):将基础的字节输出流对象进行包装
    5、图示:
    在这里插入图片描述

代码

package dems2_in_out;

import java.io.*;

public class Demo07 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\01_0803就业班\\day18\\06.LinekHashMap特点.mp4");
        FileOutputStream fos = new FileOutputStream("E:\\01_0803就业班\\day18\\06.LinekHashMap特点333.mp4");
        //创建一个高效缓冲字节输入流
        BufferedInputStream bis = new BufferedInputStream(fis);
        //创建一个高效缓冲字节输出流
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int i;
        //读取
        while((i = bis.read()) != -1){
            //写出
            bos.write(i);
        }
        //关流
        bis.close();
    //使用高效缓冲字节输出流之后,需要关闭系统资源
//获取使用刷新方法   bos.flush();
        bos.close();
    }
}

2.8 close和flush的区别

  1. close方法作用:
    (1)可以将数据从缓冲区中刷新到目标文件中
    (2)可以关闭流资源
  2. flush方法作用:
    (1)只能将数据从缓冲区刷新到目标文件中
  3. 两者关系:
    在使用close方法关闭流资源之前,系统会默认调用flush方法先刷新数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值