IO流(IO流架构图、IO操作步骤、基本输入流、缓冲处理流、转换处理流、对象流、Commins-io)

一、IO流架构图

在这里插入图片描述
字节流可以处理各种文件。包括图片、视频、音频等。
在这里插入图片描述
字符流专门用于处理字符文件,处理字符效率比字节流高。

二、IO操作步骤

  1. 建立联系 :这一步骤是为了获取流,如果此时是文件,则需要将文件抽象到内存形成对象。后期也可以是其他的数据源
  2. 选择流:从读写、数据单元和功能方面考虑。输入|输出,字节|字符,结点流|处理流。
  3. 执行操作:该读就读,该写就写。考虑是一次性完成还行需要循环。
  4. 释放资源:程序中打开的文件 IO 资源不属于内存中的资源,垃圾回收无法回收,需要显示关闭。

三、 基本输入流

字节流可以操作所有文件,字符流仅操作纯文本。

1.抽象类:InputStream 和 Reader

InputStream和Reader是所有输入流的基类,它们是两个抽象类,是所有输入流的模版,其中定义的方法在所有输入流中都可以使用。
在InputStream种常用如下几个方法:
在这里插入图片描述
在Reader中常用如下几个方法
在这里插入图片描述

[1]FileReader(字符输入流)的使用
		//创建指定文件对象
        File file=new File("F:\\iCode\\sxt\\day11\\src\\a.txt");
        //通过文件对象创建一个FileReader对象
        Reader r=new FileReader(file);
        int i=0;
        //使用Reader 对象的read()方法对字符进行读取,返回一个int类型的数据。若返回数据为-1,则说明文件中的内容已经读取完毕
        while ((i=r.read())!=-1){
            //将int类型的数据转换为char型并打印出来
            System.out.print((char) i);
        }
        r.close();

使用数组进行缓存,先把文件内容读取至指定大小的数组,再将数组中的数据取出

	 //指定数据源
        String path="F:\\iCode\\sxt\\day11\\src\\a.txt";
        //选择流
        FileReader reader = new FileReader(path);

        char[] car=new char[5];
        //读取
        int len=0;
        //reader.read(car))  将读取到的数据存储到指定的数组car中,返回本次读取字符串的长度
        while ((len=reader.read(car))!=-1){
            //通过new String(数组,开始位置,偏移量)来获得字符串
            System.out.println(new String(car,0,len));
        }

        //关闭数据源
        reader.close();
[2]FileInputStream(字节输入流)的使用
		 //确定数据源
        File file=new File("F:\\iCode\\sxt\\day11\\src\\a.txt");
        byte[] car=new byte[3];
        FileInputStream fis=null;
        try {
            //选择流
            fis = new FileInputStream(file);
            //读取
            int len = fis.read(car);
            System.out.println(len+"实际读取到的字节数");
            String s=new String(car,0,len);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭流
                if (fis!=null){
                fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

2.抽象类OutputStream 和 Writer

用于将数据从Java内存输出到其他的防的流,称为输出流,有字符也有字节。也都类似,有两个抽象类OutputStream,Writer。OutputStream和Writer也非常相似。
OutputStream 中常用如下方法:
在这里插入图片描述
在 Writer 中, 因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来代替字符数组,即以String对象来作为参数。 常用如下方法:
在这里插入图片描述

[1]FileWriter(字符输出流)的使用
 		//确定目标
        String path="src\\b.txt";
        //选择流
        FileWriter writer=new FileWriter(path);
        //写
        char[] car={'n','i','c','e'};
        writer.write(car);

        String str=" to meet you.";
        writer.write(str);
        //刷新
        writer.flush();
        //关闭资源
        writer.close();
[2]FileOutputStream(字节输出流)的使用

通过字节流完成图片的拷贝

 //确定源数据
        String source="C:\\Users\\asus\\Desktop\\picture\\email.png";
        //确定目标文件
        String target="src\\copy.png";

        //选择流
        InputStream is=new FileInputStream(source);
        OutputStream os=new FileOutputStream(target);

        byte[] car=new byte[1024];
        int len=-1;

        //边读
        while (((len=is.read(car))!=-1)){
            //边写
            os.write(car,0,len);
        }
        os.flush();
        //关闭流
        is.close();
        os.close();

四、缓冲处理流

BufferedInputStream和 BufferedReader
缓冲提高性能: 字节流缓冲流直接套在节点流上即可使用;字符缓冲流 +新增方法(不能使用多态):

1.BufferedReader

在这里插入图片描述

		//确定源数据
        String path="src\\c.txt";
        //选择流
        BufferedReader br=new BufferedReader(new FileReader(path));
        //读取
        String str=null;
        while ((str=br.readLine())!=null) {
            System.out.println(str);
        }
        //关闭流
        br.close();

2.BufferedWriter

在这里插入图片描述

在这里插入图片描述

 	//确定目标文件
        File file=new File("src\\d.txt");
        //选择流
        BufferedWriter bw=new BufferedWriter(new FileWriter(file));
        //写

        String str="谏逐客书\n" +
                "先秦:李斯\n" +
                "\n" +
                "  臣闻吏议逐客,窃以为过矣。昔缪公求士,西取由余于戎,东得百里奚于宛,迎蹇叔于宋,来丕豹、公孙支于晋。此五子者,不产于秦,而缪公用之,并国二十,遂霸西戎。孝公用商鞅之法,移风易俗,民以殷盛,国以富强,百姓乐用,诸侯亲服,获楚、魏之师,举地千里,至今治强。惠王用张仪之计,拔三川之地,西并巴、蜀,北收上郡,南取汉中,包九夷,制鄢、郢,东据成皋之险,割膏腴之壤,遂散六国之从,使之西面事秦,功施到今。昭王得范雎,废穰侯,逐华阳,强公室,杜私门,蚕食诸侯,使秦成帝业。此四君者,皆以客之功。由此观之,客何负于秦哉!向使四君却客而不内,疏士而不用,是使国无富利之实而秦无强大之名也。\n" +
                "\n" +
                "  今陛下致昆山之玉,有随、和之宝,垂明月之珠,服太阿之剑,乘纤离之马,建翠凤之旗,树灵鼍之鼓。此数宝者,秦不生一焉,而陛下说之,何也?必秦国之所生然后可,则是夜光之璧不饰朝廷,犀象之器不为玩好,郑、卫之女不充后宫,而骏良駃騠不实外厩,江南金锡不为用,西蜀丹青不为采。所以饰后宫,充下陈,娱心意,说耳目者,必出于秦然后可,则是宛珠之簪、傅玑之珥、阿缟之衣、锦绣之饰不进于前,而随俗雅化佳冶窈窕赵女不立于侧也。夫击瓮叩缶,弹筝搏髀,而歌呼呜呜快耳目者,真秦之声也;《郑》《卫》《桑间》《昭》《虞》《武》《象》者,异国之乐也。今弃击瓮叩缶而就《郑》《卫》,退弹筝而取《昭》《虞》,若是者何也?快意当前,适观而已矣。今取人则不然,不问可否,不论曲直,非秦者去,为客者逐。然则是所重者在乎色、乐、珠玉,而所轻者在乎人民也。此非所以跨海内、制诸侯之术也。\n" +
                "\n" +
                "  臣闻地广者粟多,国大者人众,兵强则士勇。是以太山不让土壤,故能成其大;河海不择细流,故能就其深;王者不却众庶,故能明其德。是以地无四方,民无异国,四时充美,鬼神降福,此五帝三王之所以无敌也。今乃弃黔首以资敌国,却宾客以业诸侯,使天下之士退而不敢西向,裹足不入秦,此所谓“藉寇兵而赍盗粮”者也。\n" +
                "\n" +
                "  夫物不产于秦,可宝者多;士不产于秦,而愿忠者众。今逐客以资敌国,损民以益仇,内自虚而外树怨于诸侯,求国无危,不可得也。";
        bw.write(str);
        bw.flush();
        //关闭流
        bw.close();

3.BufferedInputStream

在这里插入图片描述

4.BufferedOutputStream

构造器
BufferedOutputStream(OutputStream) 创建使用默认大小的输出缓冲区的缓冲字节输出流
BufferedOutputStream(OutputStream,int) 创建使用指定大小的输出缓冲区的缓冲字节输出流

方法

返回值类型方法描述
intwrite(int b)写一个int类型的字符到文件中
intwrite(byte[])将一个字节类型的数组写到文件中
intwrite(byte[],int ,int ) 将字节类型的数组写到文件中,指定开始位置和结束位置
voidflush() 刷新输出到文件中的内容
voidclose()关闭流并释放与之相关的系统资源

使用缓冲流进行文件拷贝

/**
 * 使用缓冲流拷贝文件
 */
public class Demo010 {

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

        //确定源文件
        String source="D:\\winTools\\feiGe\\repository\\第三周\\day10\\day15录像\\006ArrayList.mp4";
        //确定目标文件
        String target="E:\\arrayList.mp4";

        //选择流
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream(source));

        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(target));

        byte[] car=new byte[10*1024];
        int len=-1;
        //边读
        while (((len = bis.read(car)) != -1)) {
            //边写
            bos.write(car,0,len);
        }
        bis.close();
        bos.close();

    }
}

5.文件夹的复制

public class Test {
    public static void main(String[] args) {

        //确定源文件
        File source=new File("D:\\winTools\\feiGe\\repository\\第三周\\day10");
        //确定目标文件
        File target=new File("E:\\设计模式");
        //拷贝文件
       copyDirectory(source,target);

    }
     //拷贝文件

    static void copy(File source,File target){
        //缓冲流
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        try {
            bis=new BufferedInputStream(new FileInputStream(source));
            bos=new BufferedOutputStream(new FileOutputStream(target));
            //创建一个大小为10M的byte类型的缓存数组
            byte[] car=new byte[10*1024];
            int len=-1;
            //读 一次读取大小为10M的字节,存入car数组中
            while ((len= bis.read(car))!=-1){
                //写
                bos.write(car,0,len);
            }
            //刷新
            bos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (bis!=null){
                    bis.close();
                }
                if (bos!=null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static void copyDirectory(File sourceDir,File targetDir){
        //若目标文件夹不存在,则创建
        if (!targetDir.exists()){
            targetDir.mkdir();
        }
        //获得源文件目录下的所有子文件[夹]
        File[] files = sourceDir.listFiles();
        //遍历文件数组
        for (File file:files){
            //如果是文件
            if (file.isFile()){
                //调用复制文件的方法,文件名为当前目录+\\+文件名,拷贝至目标文件夹+\\+文件名
                copy(new File(sourceDir+"\\"+file.getName()),new File(targetDir+"\\"+file.getName()));
            }else {//如果是文件夹
                //使用递归,参数为 当前文件夹+\\+子文件夹
                copyDirectory(new File(sourceDir+"\\"+file.getName()),new File(targetDir+"\\"+file.getName()));
            }
        }
    }   
}

五、转换处理流

1.处理转换流InputStreamReader

转换流:将字节流转为字符流 处理乱码(编码集、解码集)
将文件按照指定字符编码格式读取

Reader reader = new InputStreamReader(new FileInputStream("src\\a.txt"), "gbk");
        char read =(char) reader.read();
        System.out.println(read);
        reader.close();

2.数据处理流:DataInputStream

可以处理基本类型和String类型,保留数据的类型。前提是读取顺序与写出顺序一致,否则读取数据不正确。
将数据保存至文件,并且会保存文件的数据类型

	//确定文件
        File file=new File("a.txt");
        //确定流
        DataOutputStream dos=new DataOutputStream(new FileOutputStream(file));
        //写
        //dos.writeInt(123);
        dos.writeBoolean(false);
        dos.flush();
        //关闭流
        dos.close();

六、对象流

以前我们学过的流都只能读写字节,字符形式的数据,而java中非常重要并且常见的对象类型的数据,如果想要存储到文件中应该怎么操作呢?这个时候就使用到了对象流。
序列化: 是一个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序
反序列化: 从字节流创建对象的相反的过程称为 反序列化
实体类

//实现了Serializable接口表名该类可以被序列化
public class Student implements Serializable {

    private String name;
    private int age;
    //使用了transient关键字的属性不能被序列化
    private transient boolean gender;

    public Student(String name, int age, boolean gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isGender() {
        return gender;
    }

    public void setGender(boolean gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}
/**
 *  对象输出流
 */
public class Demo004 {
    public static void main(String[] args) throws Exception{
        //目标文件
        File file=new File("a.txt");
        //选择流
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(file));
        //输出
        Student student=new Student("张三",19,true);
        oos.writeObject(student);
        //关闭流
        oos.close();
    }
}
/**
 * 对象输入流
 */
public class Demo005 {
    public static void main(String[] args) throws Exception{
        //确定数据源
        File file=new File("a.txt");
        //确定输入流
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file));
        //读
        Object o = ois.readObject();
        System.out.println(o);
        //关闭流
        ois.close();
    }
}

七、Commons-io

CommonsIO 是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url源代码等。commons-IO 需要加入classpath 的第三方jar 包内的 class 文件才能在项目中使用。

 //拷贝文件
        IOUtils.copy(new FileInputStream("a.txt"),new FileOutputStream("b.txt"));
        //这个方法适合拷贝较大的数据流,比如2G以上
        IOUtils.copyLarge(new FileReader("a.txt"),new FileWriter("c.txt"));
        //去除目录和后缀后的文件名
        System.out.println(FilenameUtils.getBaseName("a.txt"));
        // 获取文件的后缀
        System.out.println(FilenameUtils.getExtension("a.txt"));
        //复制文件夹
        FileUtils.copyDirectory(new File("out"),new File("E:\\"));
        //复制文件
        FileUtils.copyFile(new File("a.txt"),new File("d.txt"));
        //把字符串写入文件
        FileUtils.writeStringToFile(new File("a.txt"),"长太息以掩涕兮","utf-8");

        //将文件中的内容读取至字符串
        System.out.println(FileUtils.readFileToString(new File("a.txt"), "utf-8"));     
        //查看磁盘可用的空间 System.out.println(FileSystemUtils.freeSpaceKb()/1024/1024);
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值