Java基础篇之IO流,动力节点老杜详细笔记

目录

什么是IO流?  

IO流的分类 ?

怎么学好IO流?

代码演示

FileInputStream

FileOutputStream

文件的复制

FileReader

FileWriter

BufferedReader     

BufferedWriter

DataOutputStream

​DataInputStream   

PrintStream

File类

ObjectInputStream和ObjectOutputStream

IO+Properties的联合使用


什么是IO流?  

文件通常是由一连串的字节或字符构成,组成文件的字节序列 称为 字节流 ,组成文件的字符序列称为字符流 Java 中根据流的方向可以分为输入流输出流
  • 🍅I:Input,输入流是将文件或其它输入设备的数据加载到内存的过程
  • 🍅O:Output,输出流恰恰相反,是将内存中的数据保存到文件或其它输出设备

简单来说,通过IO流可以完成对硬盘文件的读和写

IO流的分类 ?

关于IO流的分类有多种分类方式

🍋一种方式是按照流的方向进行分类

  • 以内存作为参照物,往内存中去,叫做输入(Input),或者叫做读(Read),从内存中出来,叫做输出,或者叫做写(Write)

🍋一种方式是按照读取数据方式的不同来进行分类

  • 有的流是按照字节的方式读取数据,一次读取一个字节,等同于一次读取8个二进制位,这种流是万能的,什么类型的文件都可以读取,包括文本文件、图片、声音文件、视频文件等。
  • 有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取图片、声音、视频等文件,只能读取纯文本文件,连word文件都无法读取

🍋综上所述,流的分类:
                输入流输出流
                字节流字符流

举个例子,假设我们有一个文件file1.txt,里面的内容是:a中国bc张三fe

🚀采用字节流的话是这样读的:
         第一次读:一个字节,正好读到'a'
         第二次读:一个字节,正好读到'中'字符的一半
         第三次读:一个字节,正好读到'中'字符的另外一半    

🚀采用字符流的话是这样读的:
         第一次读:'a' 字符('a'字符在windows系统中占用1个字节)
         第二次读:'中' 字符('中'字符在windows系统中占用2个字节)          

怎么学好IO流?

Java中的IO流都已经写好了❤️❤️❤️(在java.io.*包下),因此程序员不需要关心具体怎么去实现,我们最主要的还是掌握如何使用就好,掌握在java中已经提供了哪些流,每个流的特点是什么,每个流对象的常用方法有哪些以及如何使用?

  • 我们要学会怎么new流对象
  • 我们要学会调用流对象的方法,知道哪个方法是读,哪个方法是写

下面首先介绍一下IO流的四大家族:

🍅1、四大家族的首领:

  • java.io.InputStream  字节输入流
  • java.io.OutputStream 字节输出流
  • java.io.Reader        字符输入流
  • java.io.Writer        字符输出流

🍅2、四大家族的首领都是抽象类(abstract class)

🍅3、所有的流都实现了 java.io.Closeable 接口,都是可关闭的,都有close()这个方法

🍅4、所有的输出流都实现了 java.io.Flushable 接口,都是可刷新的,都有flush()方法

流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会占用很多资源,因此在后面的学习和使用中要养成好习惯,用完流一定要关闭!同时,输出流在最终输出之后,也要记得使用flush()方法刷新一下,这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)(注意:如果没有flush()可能会导致数据丢失)

java.io包下需要掌握的16个流:

⭐️文件专属:

  • java.io.FileInputStream(重点掌握)     
  • java.io.FileOutputStream(重点掌握)     
  • java.io.FileReader                  
  • java.io.FileWriter                   

⭐️转换流:(将字节流转换成字符流)

  • java.io.InputStreamReader  主要是将字节输入流转换成字符输入流
  • java.io.OutputStreamWriter  主要是将字节输出流转换成字符输出流

⭐️缓冲流:(缓冲流主要是为了提高效率而存在的,它可以减少物理读取次数)

  • java.io.BufferedReader
  • java.io.BufferedWriter
  • java.io.BufferedInputStream
  • java.io.BufferedOutputStream

⭐️数据流专属:

  • java.io.DataInputStream
  • java.io.DataOutputStream

⭐️标准输出流:

  • java.io.PrintWriter
  • java.io.PrintStream(掌握)

⭐️对象流专属:

  • java.io.ObjectInputStream(掌握)
  • java.io.ObjectOutputStream(掌握)

总结一个小特点:以Writer和Reader结尾的叫字符流,以Stream结尾的叫字节流!

咋一看,哇!我要学这么多流吗?真🐂啊,其实不需要学这么多,当我们把FileInputStream和FileOutputStream这两个流学会之后,其余的就是照葫芦画瓢,非常easy!那接下来干嘛呢,赶紧上代码啊!

代码演示

FileInputStream

FileInputStream:文件字节输入流,万能的,任何类型的文件都可以采用这个流来读取

首先我们在E:\01javaSE\test这个目录下新建一个test.txt文件,然后在IDEA中编写测试代码

package com.java.javase.IO1;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        // 创建文件字节输入流对象
        FileInputStream fis=null;
        try {
            // 文件路径:E:\01javaSE\test(IDEA会自动把\编成\\,因为java中\表示转义)
            fis=new FileInputStream("E:\\01javaSE\\test\\test.txt");
            // 开始读
            while(true){
                // 调用read()方法,返回值是读取的数据所对应的ASCII码,例如读取ab,则打印出的结果是97 98
                // 当没有数据可以读取时,返回值是-1
                int readDate=fis.read();
                if(readDate==-1){
                    break;
                }
                System.out.print(readDate+" ");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在finally语句块中要确保流最后被关闭,并且被关闭的前提是流不为空(流为空也没必要关!避免空指针异常)
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

注意点:程序执行结束后,在finally语句块中确保流一定被关闭,并且关闭流的前提是流不为空,因为流是null的时候没必要关闭,这样做可以避免空指针异常!

并且上面代码中的while循环有点冗余,因此可以改造一下上面代码中的while循环:

int readDate=0;
while((readDate=fis.read())!=-1){
    System.out.print(readDate+" ");
}

改进以后我们再来分析这个程序存在哪些缺点?

一次读取一个字节(byte),这样内存和硬盘交互太频繁,会浪费大量的时间和资源在交互上面,因此我们需要对其进行改进,使其可以一次读取多个字节

read(byte[] b)方法,从此输入流中将最多b.length个字节的数据读入一个byte数组中,下面我们就使用这个方法对之前的程序进行改造,减少硬盘和内存的交互,提高程序的执行效率

package com.java.javase.IO1;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        // 创建文件字节输入流对象
        FileInputStream fis=null;
        try {
            // 文件路径:E:\01jav
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馒头爱学Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值