Java输入输出流

1.概述

输入流:读操作
输入流(InputStream及其子类)用于从外部源(如文件、网络等)读取数据到程序中,即数据流向是“进”的,被称为读操作。

输出流:写操作
输出流(OutputStream及其子类)的主要目的是将数据(如文本、字节等)从内存(或程序内部)传输到外部设备或存储介质上。这个过程本质上是将数据写出到某个目标位置,即数据流向是“出”的,被称为写操作。

2.File类

package com.stream;

import java.io.File;

public class Test {
    public static void main(String[] args) {
        //第一种创建file对象
        //File file = new File("d:\\java\\stream\\test.txt");

        //第二种创建file对象
        //File file = new File("d:\\java","stream\\test.txt");


        //第三种创建file对象
        File file0 = new File("d:\\java");
        File file = new File(file0,"stream\\test.txt");

        //判断是否是文件
        System.out.println(file.isFile());
        //判断是否是目录
        System.out.println(file.isDirectory());

        System.out.println("---------------------------");

        //创建目录
        File file2 = new File("d:\\java","set");
        //如果不存在set目录
        if(!file2.exists()){
            //则创建set目录
            file2.mkdir();
        }
        //创建多级目录
        File file3 = new File("d:\\java\\one\\two");
        if(!file3.exists()){
            //mkdirs方法创建多级目录
            file3.mkdirs();
        }

        //创建文件
        File file4 = new File("d:\\java\\one\\two\\test.txt");
        if(!file4.exists()){
            try {
                file4.createNewFile();
            }catch (Exception e){
                e.printStackTrace();
            }

        }

    }
}

3.绝对路径和相对路径

  • 绝对路径:是从盘符开始的路径
  • 相对路径:是从当前路径开始的路径
package com.stream;

import java.io.File;
import java.io.IOException;

public class Test2 {
    public static void main(String[] args) {
        File file = new File("set\\test.txt");
        if (!file.exists()) {
            try {
                file.createNewFile();

            }catch (IOException e) {
                e.printStackTrace();
            }
        }

        //判断是否是绝对路径
        System.out.println(file.isAbsolute());
        //获取相对路径
        System.out.println(file.getPath());
        //获取绝对路径
        System.out.println(file.getAbsolutePath());
        //获取文件名
        System.out.println(file.getName());

    }

}

4.字节流

  • 字节输入流InputStream
  • 字节输出流OutputStream
  • 适合二进制数据相关的操作,不太适合处理中文相关文本数据。

字节输入流:
在这里插入图片描述

字节输出流:
在这里插入图片描述

5.FileInputStream(字节文件输入流)

  • 从文件系统中的某个文件中获得输入字节(读取文件中的内容到内存或程序中)
  • 用于读取诸如图像数据之类的原始字节流

FileInputStream方法
在这里插入图片描述

例1:

package com.imooc.stream;

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

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

        try {
            //创建一个FileInputStream对象(文件输入流)
            FileInputStream fis = new FileInputStream("set\\test.txt");
            int i = fis.read();
            while (i != -1) { //没有到达文件内容末尾
                System.out.print((char) i);
                i = fis.read();//再接着读取
            }
            fis.close();//关闭输入流
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
                e.printStackTrace();
        }

    }
}

例2:

package com.imooc.stream;

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

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

        try {
            //创建一个FileInputStream对象(文件输入流)
            FileInputStream fis = new FileInputStream("set\\test.txt");
            byte[] b = new byte[50];//生成一个长度50的字节数组
            fis.read(b);//把数据读到byte类型的数组中
            System.out.println(new String(b));
            fis.close();//关闭输入流
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}

6.FileOutputStream(字节文件输出流)

例:

package com.imooc.stream;

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

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        try {
            //创建一个字节文件输出流对象
            FileOutputStream fos = new FileOutputStream("set\\test.txt",true);//true:表示往之前的内容后面追加,否则就覆盖
            fos.write(50);
            fos.write('a');
            fos.write('b');
            fos.close();//关闭输出流

        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }


    }
}

7.字符流

  • 字符输入流Reader
  • 字符输出流Writer
  • 适合操作中文相关的文本数据

Reader:在这里插入图片描述

Writer:
在这里插入图片描述

8.字节字符转换流

  • InputStreamReader :将字节输入流转换为字符输入流,用于读取文本数据
  • OutputStreamWriter:将字节输出流转换为字符输出流,用于向文件写数据

InputStreamReader :

package com.imooc.stream;

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

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

        try {
            FileInputStream fis = new FileInputStream("set\\a.txt");
            InputStreamReader isr = new InputStreamReader(fis);//流的连接
            //读取数据
            int n=0;
            while ((n=isr.read())!=-1){
                System.out.print((char) n);//这样中文读出来就没有乱码问题
            }
            fis.close();
            isr.close();

        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

OutputStreamWriter:

package com.imooc.stream;

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

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

        try {
            //创建一个字节输出流
            FileOutputStream fos = new FileOutputStream("set\\b.txt");
            //使用 OutputStreamWriter 包装 FileOutputStream
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            osw.write("你好世界!abc");//
            /*
            流关闭顺序:
            当使用 OutputStreamWriter 包装 FileOutputStream 时,
            只需要关闭最外层的包装流(在这个例子中是 OutputStreamWriter),
            因为关闭包装流也会关闭它所包装的所有底层流。
            然而,显式关闭两者通常不会导致错误,但这不是必要的,
            并且如果底层流(FileOutputStream)在包装流(OutputStreamWriter)之前被关闭,
            则可能会引发异常。但最好是只关闭 osw。
             */
            osw.close();//
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

9.BufferedReader

BufferedReader 是 Java 中用于读取文本的一个类,它包装了其他字符输入流,如 FileReader,提供了缓冲字符输入以及按行读取文本的功能。BufferedReader 提高了读取效率,因为它内部使用了一个字符缓冲区来存储从源读取的字符,从而减少了实际读取操作的次数。

使用 BufferedReader 读取文件时,你通常会按照以下步骤进行:

  1. 创建 FileReader:首先,你需要创建一个 FileReader 对象,该对象将作为 BufferedReader 的源。FileReader 是用于读取字符文件的便利类。
  2. 包装 BufferedReader:然后,使用 FileReader 对象作为参数来创建 BufferedReader 对象。
  3. 读取数据:通过 BufferedReader 提供的 readLine() 方法,你可以按行读取文本。该方法会读取包含行终止符(如换行符)的字符序列,直到但不包括下一个行终止符,然后将这些字符作为字符串返回。如果已到达流的末尾,则返回 null。
  4. 关闭流:最后,完成读取后,你应该关闭 BufferedReader 和它包装的 FileReader 以释放与之关联的系统资源。由于 BufferedReader 封装了 FileReader,所以只需要关闭 BufferedReader 即可,它会负责关闭底层的 FileReader。

例:

package com.imooc.stream;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample {
    public static void main(String[] args) {
        try {
            FileReader fileReader = new FileReader("set\\b.txt");
            BufferedReader br = new BufferedReader(fileReader);
            String line;
            while ((line= br.readLine())!=null){
                System.out.println(line);
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}

10.对象的序列化和反序列化

步骤:

  • 创建一个类,实现Serializable接口
  • 创建对象
  • 将对象写入文件
  • 从文件读取对象信息

对象的序列化涉及到两个类

  • 对象输入流ObjectInputStream
  • 对象输出流ObjectOutputStream

序列化:把Java对象转换为字节序列的过程
反序列化:把字节序列恢复为Java对象的过程

例:

Goods类实现Serializable接口

package com.imooc.stream;

import java.io.Serializable;

public class Goods implements Serializable {
    private int id;
    private String name;
    private double price;

    public Goods(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

测试:

package com.imooc.stream;

import java.io.*;

public class GoodsTest {
    public static void main(String[] args) {
        //创建Goods类对象
        Goods goods1 = new Goods(1, "电脑", 50);
        //先把对象写入文件
        try (
                //try-with-resources 语句来自动管理资源,即使在发生异常时也能正确关闭资源
                //1.定义一个文件输出流
                FileOutputStream fileOutputStream = new FileOutputStream("set/goods.txt");
                //2.定义一个对象输出流,并将文件输出流连接到对象输出流
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

                //3.使用文件输入流进行对象读取
                FileInputStream fileInputStream = new FileInputStream("set/goods.txt");
                //对象输入流连接到文件输入流
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        ) {

            //3.goods1对象存到文件中
            objectOutputStream.writeObject(goods1);
            //4.读取对象并输出
            System.out.println(objectInputStream.readObject());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }


    }
}

11.try-with-resources 语句

try-with-resources 语句特性:

  1. try-with-resources 语句是 Java 7引入的一个特性,它用于自动管理资源,确保每个资源在语句结束时都能被正确关闭。这主要适用于实现了java.lang.AutoCloseable 接口(或继承自 java.io.Closeable 接口,因为 Closeable继承自 AutoCloseable)的资源,如文件流、数据库连接等。
  2. 使用 try-with-resources 语句时,你可以将一个或多个资源放在 try 语句的括号 () 中,这些资源在 try 代码块执行前被初始化,并在 try 代码块执行完毕后(无论是否发生异常)自动关闭。

使用传统的 try-finally 手动资源关闭存在的问题:

  1. 容易忘记关闭资源,从而引发内存泄漏
  2. 资源比较多的时候,代码嵌套层次较深,代码可读性不佳
  3. try 块与 finally 块同时发生异常时,存在异常压制问题
  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值