IO流--千锋视频笔记

本文详细介绍了Java中的I/O流,包括流的概念、分类、字节流、字符流、对象流、缓冲流、字符缓冲流、PrintWriter、转换流、File类的使用以及Properties特性。讲解了文件读写、图片复制、对象序列化与反序列化等实例,涵盖了字节流与字符流的使用,以及文件操作和编码方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I/O 框架

1、流的概念

内存与存储设备之间传输数据的通道

img

2、流的分类

1、按方向【重点】

  • 输入流:将<存储设备>中的内容读到<内存>中
  • 输出流:将<内存>中的内容写到<存储设备>中

2、按单位

  • 字节流:以字节为单位,可以读写所有数据
  • 字符流:以字符为单位,只能读写文本数据

3、按功能

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础之上增强功能

3、字节流

字节流的父类(抽象类)

//InputStream 字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}

// OutputStream 字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b, int off, int len){}

1、文件字节流

​ (1)文件输入流

public class FileInput {
    public static void main(String[] args) throws IOException {
        //1、创建FileInputStream,并指定文件路径
        FileInputStream fileInputStream = new FileInputStream("F:\\idea\\temp\\aaa.txt");
        //2、读取文件
        //单个字节读取
//        int data=0;
//        while ((data=fileInputStream.read())!=-1){
//            System.out.print((char)data);
//        }
        //一次读取多个字节,把多个字节放在一个数组里
        byte[] buf=new byte[4];
        int count=0;
        while ((count=fileInputStream.read(buf))!=-1){
            System.out.println(new String(buf,0,count));  //new String()转换为字符串,(buf,0,count)输出存到buf中的数据,count判断个数,最后多余的数抵消不显示
        }
        //3、关闭
        fileInputStream.close();
        System.out.println("执行完毕");
    }
}

​ (2)文件输出流

public class FileOutput {
    public static void main(String[] args) throws IOException {
        //1、创建文件字节输出流对象
        FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\temp\\bbb.txt",true);//不加true则表示覆盖,加上则表示重写
        //2、写入文件
        String str ="Hello,World";
        fileOutputStream.write(str.getBytes());
        //3、关闭
        fileOutputStream.close();
        System.out.println("执行完毕");
    }
}

2、图片复制案例

public class FileCopy {
    public static void main(String[] args)throws Exception {
        //1、创建流
        //文件字节输入流
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\简历\\成绩单.jpg");//注意用\\或者//而不是\
        //文件字节输出流
        FileOutputStream fileOutputStream = new FileOutputStream("F://idea//temp//成绩copy.jpg");
        //2、一边读、一边写
        byte[] buf =new byte[1024];
        int count =0;
        while ((count=fileInputStream.read(buf))!=-1){
            fileOutputStream.write(buf,0,count);
        }
        //3、关闭
        fileInputStream.close();
        fileOutputStream.close();
        System.out.println("执行完毕");
    }
}

3、字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream
  • 提高IO效率,减少访问磁盘次数
  • 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
public class BufferedInput {
    public static void main(String[] args) throws Exception{
        //1、创建缓冲流,文件读取的字节存入到缓冲流中
        FileInputStream fis = new FileInputStream("F:\\idea\\temp\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //2、读取
        int data=0;
        while ((data= bis.read())!=-1){
            System.out.println((char) data);
        }
        //或者自己设置缓冲区
//        byte[] buf=new byte[1024];
//        int count=0;
//        while ((count= bis.read(buf))!=-1){
//            System.out.println(new String(buf,0,count));
//        }
        bis.close();
    }
}
public class BufferedOutput {
    public static void main(String[] args) throws Exception {
        //1、创建文件ccc和字节输出流
        FileOutputStream fos = new FileOutputStream("F:\\idea\\temp\\ccc.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //2、写入文件
        for (int i=0;i<10;i++){
            bos.write("hello world\r\n".getBytes());//把hello world写入缓冲区
            bos.flush();//刷新到硬盘
        }
        System.out.println("执行完毕");
        //3、关闭
        bos.close();
    }
}

4、对象流

ObjectOutputStream / ObjectInputStream
  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串的功能
  • 增强了读写对象的功能
    • readObject() 从流中读取一个对象
    • writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程称为序列化、反序列化

5、序列化与反序列化

1、序列化

/**
 * ObjectOutputStream实现对象的序列化(写入文件),把对象写在硬盘上
 * 序列化的类必须实现Serializable接口
 */
public class ObjectOutput {
    public static void main(String[] args) throws Exception {
        // 1. 创建对象流
        FileOutputStream fos = new  FileOutputStream("F:\\idea\\temp\\stu.bin");//bin二进制的文件
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        // 2. 序列化(写入操作)
        Student zhangsan = new Student(20,"张三");
        oos.writeObject(zhangsan);
        // 3. 关闭
        oos.close();
        System.out.println("序列化执行完毕");
    }
}

2、反序列化

public class ObjectInput {
    public static void main(String[] args) throws Exception{
        //1、创建对象流
        FileInputStream fis = new FileInputStream("F:\\idea\\temp\\stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2、读取文件(反序列化操作)
        Student s = (Student) ois.readObject();
        System.out.println(s.toString());
        //3、关闭
        ois.close();
        System.out.println("反序列化执行完毕");
    }
}

3、注意事项

  1. 某个类要想序列化必须实现Serializable接口
  2. 序列化类中对象属性要求实现Serializable接口
  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  4. 使用transient修饰属性,这个属性就不能序列化
  5. 静态属性不能序列化
  6. 序列化多个对象,可以借助集合来实现

序列化多个对象,可以借助集合来实现代码展示:

public class ObjectOutput {
    public static void main(String[] args) throws Exception {
        // 1. 创建对象流
        FileOutputStream fos = new  FileOutputStream("F:\\idea\\temp\\stu.bin");//bin二进制的文件
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        // 2. 序列化(写入操作)
        //写入多个
        Student lisi =new Student(20,"李四");
        Student wangwu =new Student(20,"王五");
        ArrayList<Student> list = new ArrayList<>();
        list.add(lisi);
        list.add(wangwu);
        oos.writeObject(list);
        // 3. 关闭
        oos.close();
        System.out.println("序列化执行完毕");
    }
}
public class ObjectInput {
    public static void main(String[] args) throws Exception{
        //1、创建对象流
        FileInputStream fis = new FileInputStream("F:\\idea\\temp\\stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2、读取文件(反序列化操作)
        //读多个对象
        ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
        System.out.println(list.toString());
        //3、关闭
        ois.close();
        System.out.println("反序列化执行完毕");
    }
}

6、编码方式

UTF-8:针对Unicode的编码的可变长字符编码

GBK:简体中文,扩充

7、字符流

1、字符流的父类(抽象类)

reader 字符输入流

  • public int read(){}
  • public int read(char[] c){}
  • public int read(char[] b, int off, int len){}

Writer 字符输出流

  • public void write(int n){}

  • public void write(String str){}

  • public void write(char[] c){}

public class FileRead {
    public static void main(String[] args) throws Exception {
        //1、创建FileReader文件字符流输入流
        FileReader fr = new FileReader("F:\\idea\\temp\\aaa.txt");
        //2、读取
        //一个一个字符读取
//        int data=0;
//        while ((data= fr.read())!=-1){
//            System.out.print((char) data);
//        }
        //创建字符缓冲区
        char[] chars = new char[1024];
        int count=0;
        while ((count= fr.read(chars))!=-1){
            System.out.print(new String(chars,0,count));
        }
        //3、关闭
        fr.close();
    }
}
public class FileWrite {
    public static void main(String[] args) throws Exception{
        // 1. 创建FileWriter对象
        FileWriter fw = new FileWriter("F:\\idea\\temp\\ddd.txt");
        // 2. 写入
        for(int i = 0; i < 10; i ++){
            fw.write("写入内容\n");
        }
        // 3. 关闭
        fw.close();
        System.out.println("执行完毕");
    }
}

2、字符流进行文本文件复制

不能复制图片或二进制文件,使用字节流可以复制任意文件

public class FileCopy {
    public static void main(String[] args) throws Exception {
        // 1. 创建
        FileReader fr = new FileReader("F:\\idea\\temp\\ddd.txt");
        FileWriter fw = new FileWriter("F:\\idea\\temp\\eee.txt");
        // 2. 读写
        int data = 0;
        while((data = fr.read()) != -1){
            fw.write(data);
        }
        // 3. 关闭
        fw.close();
        fr.close();
        System.out.println("执行完毕");
    }
}

3、字符缓冲流

BufferedReader / BufferedWriter

高效读写、支持输入换行符、可一次写一行读一行

public class BufferedRead {
    public static void main(String[] args) throws Exception {
        // 创建缓冲流
        FileReader fr = new FileReader("F:\\idea\\temp\\eee.txt");
        BufferedReader br = new BufferedReader(fr);
        // 读取
        // 1. 第一种方式
        char[] buf = new char[1024];
        int count = 0;
        while((count = br.read(buf)) != -1){
            System.out.println(new String(buf, 0, count));
        }
        // 2. 第二种方式 一行一行读取
        String line = null;
        while((line = br.readLine()) != null){
            System.out.println(line);
        }
        // 关闭
        br.close();
    }
}
public class BufferedWrite {
    public static void main(String[] args) throws Exception {
            // 1. 创建BufferedWriter对象
            FileWriter fw = new FileWriter("F:\\idea\\temp\\fff.txt");
            BufferedWriter bw = new BufferedWriter(fw);
            // 2. 写入
            for(int i = 0; i < 10; i ++){
                bw.write("写入的内容");
                bw.newLine(); // 写入一个换行符 代替/n
            }
            // 3. 关闭
            bw.close(); // 此时会自动关闭fw
        System.out.println("执行完毕");
    }
}

4、PrintWriter

封装了print() / println() 方法

支持写入后换行

支持数据原样打印

psvm(String[] args){
  // 1 创建打印流
  PrintWriter pw = new PrintWriter("..");
  // 2 打印
  pw.println(12);
  pw.println(true);
  pw.println(3.14);
  pw.println('a');
  // 3 关闭
  pw.close();
}

5、转换流

桥转换流 InputStreamReader / OutputStreamWriter

可将字节流转换为字符流

可设置字符的编码方式

//InputStreamReader读取文件指定使用的编码,字节流通向字符流的桥梁,由硬盘的字节到内存的字符
public class InputStreamRead {
    public static void main(String[] args) throws Exception {
            // 1 创建InputStreamReader对象
            FileInputStream fis = new FileInputStream("F:\\idea\\temp\\ddd.txt");
            InputStreamReader isr = new InputStreamReader(fis, "utf-8"); //保证文件编码和指定编码一致
            // 2 读取文件
            int data = 0;
            while((data = isr.read()) != -1){
                System.out.print((char)data);
            }
            // 3 关闭
            isr.close();
            System.out.println("执行完成");
    }
}


//OutputStreamWriter写入文件,使用指定编码,字符流通向字节流的桥梁,由内存的字符到硬盘的字节
public class OutputStreamW {
    public static void main(String[] args) throws Exception{
        // 1 创建OutputStreamReader对象
        FileOutputStream fos = new FileOutputStream("F:\\idea\\temp\\ddd.txt",true);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
        // 2 写入
        for(int i = 0; i < 10; i ++){
            osw.write("写入内容");
        }
        // 3 关闭
        osw.close();
        System.out.println("执行完成");
    }
}

8、File类

概念:代表物理盘符中的一个文件或者文件夹

1、file的基本使用


/**
 * File类的使用
 * 1. 分隔符
 * 2. 文件操作
 * 3. 文件夹操作
 */

public class FileTitle{
    public static void main(String[] args) throws Exception{
//        separator();
//        fileOpen();
        folder();
    }
    // 1. 分隔符
    public static void separator(){
        System.out.println("路径分隔符" + File.pathSeparator);
        System.out.println("名称分隔符" + File.separator);
    }
    // 2. 文件操作
    public static void fileOpen() throws Exception{
        // 1. 创建文件
        File file = new File("F:\\idea\\temp\\file.txt");
        if (!file.exists()) {   //不存在就创建
            boolean b = file.createNewFile();
            System.out.println("创建结果:" + b);
        }
        // 1 创建打印流
        PrintWriter pw = new PrintWriter("F:\\idea\\temp\\file.txt");
        // 2 打印
        pw.println(97);  //打印出来就是97,不是a
        pw.println(true);
        pw.println(3.14);
        pw.println('a');
        pw.println("张");
        // 3 关闭
        pw.close();
//        // 2. 删除文件
//        // 2.1 直接删除
//        file.delete(); // 成功true
//        // 2.2 使用jvm退出时删除
//        file.deleteOnExit();
//        Thread.sleep(5000);  //休眠5s后jvm退出->删除

        // 3. 获取文件信息
        System.out.println("获取绝对路径" + file.getAbsolutePath());
        System.out.println("获取路径" + file.getPath());
        System.out.println("获取文件名称" + file.getName());
        System.out.println("获取夫目录" + file.getParent());
        System.out.println("获取文件长度" + file.length());
        System.out.println("文件创建时间" + new Date(file.lastModified()).toLocaleString());

        // 4. 判断
        System.out.println("是否可写" + file.canWrite());
        System.out.println("是否是文件" + file.isFile());
        System.out.println("是否隐藏" + file.isHidden());
    }

    // 文件夹操作
    public static void folder() throws Exception {
        // 1. 创建文件夹
        File dir = new File("F:\\idea\\temp\\file");
        System.out.println(dir.toString());
        if (!dir.exists()) {
            //dir.mkdir(); // 只能创建单级目录
            dir.mkdirs(); // 创建多级目录
        }

//        // 2. 删除文件夹
//        // 2.1 直接删除
//        dir.delete(); // 只能删除最底层空目录
//        // 2.2 使用jvm删除
//        dir.deleteOnExit();
//        Thread.sleep(5000);

        // 3. 获取文件夹信息
        System.out.println("获取绝对路径" + dir.getAbsolutePath());
        System.out.println("获取路径" + dir.getPath());
        System.out.println("获取文件名称" + dir.getName());
        System.out.println("获取夫目录" + dir.getParent());
        System.out.println("获取文件长度" + dir.length());
        System.out.println("文件夹创建时间" + new Date(dir.lastModified()).toLocaleString());

        // 4. 判断
        System.out.println("是否是文件夹" + dir.isFile());
        System.out.println("是否隐藏" + dir.isHidden());

        // 5. 遍历文件夹
        File dir2 = new File("F:\\idea\\temp");
        String[] files = dir2.list();
        for (String fi : files) {
            System.out.println(fi);
        }
        System.out.println("====================================");
        // FileFilter过滤接口的使用
        File[] files2=dir2.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if(pathname.getName().endsWith(".txt")){
                    return true;
                }
                return false;
            }
        });
        for (File file : files2) {
            System.out.println(file.getName());
        }
    }
}

2、file案例

/**
 * 案例:
 * 1、递归遍历文件夹
 * 2、递归删除文件夹
 */
public class FileCase {
    public static void main(String[] args) throws Exception {
            listDir(new File("F:\\idea\\temp"));
            deleteDir(new File("F:\\idea\\temp\\file"));
        }

        public static void listDir(File dir) {
            File[] files = dir.listFiles();  //把文件夹或者文件存入数组
            System.out.println(dir.getAbsolutePath());
            if (files != null && files.length > 0) {
                for (File file : files) {
                    if (file.isDirectory()) { //如果是文件夹
                        listDir(file); // 递归
                    } else {
                        System.out.println(file.getAbsolutePath());
                    }
                }
            }
        }
    public static void deleteDir(File dir){
        File[] files = dir.listFiles();
        if(files != null && files.length > 0){
            for(File file : files){
                if(file.isDirectory()){
                    deleteDir(file); // 递归
                }else{
                    // 删除文件
                    System.out.println(file.getAbsolutePath() + "删除结果为:" + file.delete());
                }
            }
        }
        System.out.println(dir.getAbsolutePath() + "删除结果为:" + dir.delete());
    }
}

补充:Properties

1、Properties特点

  1. 属性集合
  2. 存储属性名和属性值
  3. 没有泛型
  4. 和流有关

2、Properties与流相关的方法

public class Properties01 {
    public static void main(String[] args) throws Exception{
        //1、创建集合
        Properties properties = new Properties();
        //2、添加数据
        properties.setProperty("username","zhangsan");
        properties.setProperty("age","20");
        System.out.println(properties.toString());
        //3、遍历
        /*
        1、keySet
        2、entrySet
        3、stringpropertyNames
         */
        Set<String> pname = properties.stringPropertyNames();
        for (String s : pname) {
            System.out.println(s+"==="+ properties.getProperty(s));
        }
        //4、和流相关的用法
        // 1、list方法
//        PrintWriter pw = new PrintWriter("F:\\idea\\temp\\aaa.txt");
//        properties.list(pw);
//        pw.close();
        //2、store保存
//        FileOutputStream fos = new FileOutputStream("F:\\idea\\temp\\aaa.properties");
//        properties.store(fos,"注释");
//        fos.close();
        //3、load加载方法
        Properties properties1 = new Properties();
        FileInputStream fis = new FileInputStream("F:\\idea\\temp\\aaa.properties");
        properties1.load(fis);
        fis.close();
        System.out.println(properties1.toString());
    }
}

println(s+“===”+ properties.getProperty(s));
}
//4、和流相关的用法
// 1、list方法
// PrintWriter pw = new PrintWriter(“F:\idea\temp\aaa.txt”);
// properties.list(pw);
// pw.close();
//2、store保存
// FileOutputStream fos = new FileOutputStream(“F:\idea\temp\aaa.properties”);
// properties.store(fos,“注释”);
// fos.close();
//3、load加载方法
Properties properties1 = new Properties();
FileInputStream fis = new FileInputStream(“F:\idea\temp\aaa.properties”);
properties1.load(fis);
fis.close();
System.out.println(properties1.toString());
}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值