Java学习笔记 - IO流


流的分类

按操作数据单位分:字节流(二进制文件),字符流(文本文件)
按流向分:输入流,输出流
按流的角色分:节点流,处理流(包装流)
以下是部分IO流所涉及的类的继承关系:
在这里插入图片描述
在这里插入图片描述

节点流与处理流

节点流:
是底层流 / 低级流,它直接与数据相联系。
处理流:
也叫包装流,对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相联系,不仅可以消除不同节点流的使用差别,还提供了简便的方法来完成数据的输入与输出。

处理流的优点:

  1. 性能提高:主要以增加缓冲的方式来提高数据输入输出的效率
  2. 操作便捷:处理流提供了一系列便捷的方法来一次性输入输出大批量的数据,使用时更加方便灵活

创建文件方式

常用的两种创建文件方式、创建目录的方式、获取文件基本信息的方法:

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

public class GetFileInfo {
    public static void main(String[] args) {
        create1();
//        create2();
        File file = new File("E:\\file1.txt");
        System.out.println("文件名字:" + file.getName());
        System.out.println("文件绝对路径:" + file.getAbsolutePath());
        System.out.println("文件父目录:" + file.getParent());
        System.out.println("文件字节大小:" + file.length());
        System.out.println("文件是否存在:" + file.exists());
        System.out.println("是不是一个文件:" + file.isFile());
        System.out.println("是不是一个目录:" + file.isDirectory());
    }
//创建文件方法1
    public static void create1() {
        String filePath = "E:\\file1.txt";
        File file = new File(filePath);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件创建成功。");
    }
    
//创建文件方法2
    public static void create2() {
        String parentFile = "E:\\";
        String name = "file2.txt";
        File file = new File(parentFile, name);
        try {
            file.createNewFile();
            System.out.println("文件创建成功。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

//创建目录方法
    public static void createDirectory() {
        String filePath = "E:\\dir1";
        File file = new File(filePath);
        file.mkdirs();
        System.out.println("目录创建成功。");
    }
}

字节流

InputStream – 输入流

InputStream 是一个抽象类,是所有字节 输入类(流)的超类

FileInputStream – 文件字节输入流

import java.io.FileInputStream;

public class FileInputStream01 {
    public static void main(String[] args) throws Exception{
        String filePath = "E:\\a.txt";
        FileInputStream fileInputStream = new FileInputStream(filePath);
        int readData = 0;
        while ((readData = fileInputStream.read()) != -1){
            System.out.print((char)readData);//转成char显示
        }
        fileInputStream.close();
    }
}

BufferedInputStream – 缓冲字节输入流

import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class BufferedInputStream01 {
    public static void main(String[] args) throws Exception{
        String filePath = "e:\\a1.txt";
        int readData = 0;
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
        while ((readData = bufferedInputStream.read()) != -1){
            System.out.print((char)readData);//转成char显示
        }
        bufferedInputStream.close();
    }
}

ObjectInputStream – 对象字节输入流

序列化与反序列化:

序列化,就是在保存数据时,同时保存数据的值数据类型
反序列化,就是在恢复数据时,同时恢复数据的值数据类型
条件:
需要序列化的对象必须是实现了 Serializable或者Externalizable接口的类(可序列化的类)才行。
平时一般是去实现Serializable接口,它是一个标记接口,没有需要实现的方法,而Externalizable接口有需要实现的方法,使用时相对繁琐,而且它也是继承了Serializable接口的。

使用时的注意事项与细节说明:

1、数据的读与写的顺序要一致
2、序列化与反序列化的对象需要实现Serializable接口
3、序列化的类中建议添加 “ private static final long serialVersionUID = 1L;”属性语句,这样能提高版本的兼容性
4、序列化对象时,默认将 除了static 或 transient 修饰的 成员全部序列化
5、序列化对象时,其对象所属类里面的属性也需要时2实现了Serializable接口的
6、序列化具有可继承性,也就是某类已经实现了序列化,则它的所有子类也默认实现了序列化

import java.io.*;

public class ObjectInputStream01 {
    public static void main(String[] args) throws Exception {
        String filePath = "e:\\data.dat";//指定需反序列化的文件
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        //1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
        //2. 否则会出现异常
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());

        ois.close();
        System.out.println("反序列化完成");
    }
}

OutputStream – 输出流

OutputStream 是一个抽象类,是所有字节 输出类(流)的超类

FileOutputStream – 文件字节输出流

import org.junit.Test;
import java.io.FileOutputStream;

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

    }

    @Test
    public void writeFile() throws Exception {
        String filePath = "E:\\a.txt";
        FileOutputStream fileoutputStream = null;

//new FileOutputStream(filePath)覆盖方式,覆盖原有内容
//new FileOutputStream(filePath,true)追加方式,从原有内容最后开始写入
        fileoutputStream = new FileOutputStream(filePath, true);
        String str = "hello,world!";
        //str.getBytes()把字符串转换为字节数组
        fileoutputStream.write(str.getBytes());
        fileoutputStream.close();
    }
}

BufferedOutputStream – 缓冲字节输出流

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class BufferedOutputStream01 {
    public static void main(String[] args) throws Exception{
        String filePath = "e:\\a1.txt";
        String str = "hello,world!";
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
        bufferedOutputStream.write(str.getBytes());
        bufferedOutputStream.close();
    }
}

ObjectOutputStream – 对象字节输出流

import java.io.*;

public class ObjectOutStream01 {
    public static void main(String[] args) throws Exception {
        //序列化后,保存的文件格式不是存文本,而是按照他自己的格式来保存
        String filePath = "e:\\data.dat";//序列化数据到 e:\data.dat
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        oos.writeInt(100);// int -> Integer (实现了 Serializable)
        oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
        oos.writeChar('a');// char -> Character (实现了 Serializable)
        oos.writeDouble(11.1);// double -> Double (实现了 Serializable)
        oos.writeUTF("你好!");//String
        
        oos.close();
        System.out.println("序列化结束。");
    }
}

PrintStream

System.in :标准输入,是InputStream类型,默认设备为 键盘
System.out :标准输出,是PrintStream类型,默认设备为 显示器

import java.io.IOException;
import java.io.PrintStream;

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

        PrintStream out = System.out;
        //System.out -> PrintStream类型
        //在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
        out.print("hi!");
        //因为print底层使用的是write , 所以我们可以直接调用write进行打印/输出
        out.write("你好01。".getBytes());
        out.close();

        //我们可以去修改打印流输出的位置/设备,如:
        //1. 输出修改成到 "e:\\a.txt"
        //2. "你好02." 就会输出到 e:\a.txt
        PrintStream ps = new PrintStream("e:\\a.txt");
        System.setOut(ps);
        System.out.println("你好02.");
    }
}

字符流

Reader – 输入流

Reader 是一个抽象类,是所有字符 输入类(流)的超类

FileReader – 文件字符输入流

import org.junit.Test;

import java.io.FileReader;

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

    }

    //单个字符读取文件
    @Test
    public void readFile01() throws Exception {
        String filePath = "e:\\a1.txt";
        //1. 创建FileReader对象
        FileReader fileReader = new FileReader(filePath);
        int data = 0;
        //循环读取 使用read, 单个字符读取
        while ((data = fileReader.read()) != -1) {
            System.out.print((char) data);
        }
        fileReader.close();
    }

    //字符数组读取文件
    @Test
    public void readFile02() throws Exception {
        String filePath = "e:\\a1.txt";
        //1. 创建FileReader对象
        FileReader fileReader = new FileReader(filePath);
        int readLen = 0;
        char[] buf = new char[8];
        //循环读取 使用read(buf), 返回的是实际读取到的字符数
        //如果返回-1, 说明到文件结束
        while ((readLen = fileReader.read(buf)) != -1) {
            System.out.print(new String(buf, 0, readLen));
        }
        fileReader.close();
    }
}

BufferedReader – 缓冲字符输入流

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferedReader01 {
    public static void main(String[] args) throws Exception {
        String filePath = "e:\\a1.txt";
        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line; //获取读取到的字符串
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }
}

InputStreamReader – 转换流

转换流,完成字节流向字符流的转换。
在处理纯文本文件时,使用字符流效率更高,这时就可以使用转换流将字节流转换为字符流使用,并且可以在使用时指定需要的编码格式(比如:UTF-8,GBK 等),有效解决中文乱码问题

InputStreamReader 是 Reader的子类,可以将 InputStream的子类(字节流)包装(或叫转换)成为 Reader的子类(字符流)

import java.io.*;

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

        String filePath = "e:\\a.txt";
        String charSet = "gbk";
        //1. 把 FileInputStream 转成 InputStreamReader后传入BufferedReader
        //2. 指定编码 gbk

        //方式1,分开写
        //InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), charSet);
        //BufferedReader br = new BufferedReader(isr);

        //方式2,连起来写
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charSet));
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//按默认编码方式读取

        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }

        br.close();
        System.out.println("按照 " + charSet + " 编码方式读取文件成功。");
    }
}

Writer – 输出流

Writer 是一个抽象类,是所有字符 输出类(流)的超类

FileWriter – 文件字符输出流

注意:
FileWriter 使用完后,必须 close() 关闭 或者 flush() 刷新 否则写入不到相应的文件中去

import java.io.FileWriter;

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

        String filePath = "e:\\a2.txt";
        //创建FileWriter对象
        FileWriter fileWriter = new FileWriter(filePath);
//write(int):写入单个字符
        fileWriter.write('A');
//write(char[]):写入指定数组
        char[] chars = {'a', 'b', 'c'};
        fileWriter.write(chars);
//write(string):写入整个字符串
        fileWriter.write("很高兴见到你。");
        fileWriter.write("你好!");
//write(string,off,len):写入字符串的指定部分
        fileWriter.write("很高兴见到你。", 1, 2);

        fileWriter.close();//必须有关闭操作,否则无法把数据写入到文件中
        System.out.println("程序结束...");
    }
}

BufferedWriter – 缓冲字符输出流

它是一种处理流(也叫包装流),可以把Writer的所有子类包装在它里面,为程序提供更为强大的读写功能,在关流时,也只需要关闭外层流即可,它的内部会自动关闭内层的流

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "e:\\a4.txt";
        //1. new FileWriter(filePath, true) 表示以追加的方式写入
        //2. new FileWriter(filePath) , 表示以覆盖的方式写入
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
        bufferedWriter.write("内容1");
        bufferedWriter.newLine();
        bufferedWriter.write("内容2");
        bufferedWriter.newLine();
        bufferedWriter.write("内容3");
        bufferedWriter.newLine();
        bufferedWriter.write("内容4");
        bufferedWriter.newLine();
        bufferedWriter.write("内容5");
        bufferedWriter.newLine();
        //......

        bufferedWriter.close();
    }
}

OutputStreamWriter – 转换流

import java.io.*;

public class OutputStreamWriter01 {
    public static void main(String[] args) throws Exception {
        String filePath = "e:\\a.txt";
        String charSet = "gbk";

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath),charSet));
//        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath)));//按默认编码方式保存

        bw.write("hi!");
        bw.newLine();
        bw.write("你好!");
        bw.newLine();

        bw.close();
        System.out.println("按照 " + charSet + " 编码方式保存文件成功。");
    }
}

PrintWriter

import java.io.FileWriter;
import java.io.PrintWriter;

public class PrintWriter01 {
    public static void main(String[] args) throws Exception{
        String filePath = "e:\\a.txt";
        //数据输出到文件 e:\a.txt 中
        PrintWriter printWriter = new PrintWriter(new FileWriter(filePath));
        //数据输出到控制台中,System.out -> 标准输出(控制台显示屏)
//        PrintWriter printWriter = new PrintWriter(System.out);
        printWriter.write("你好。");

        printWriter.close();
    }
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值