Java高级之IO流

1 IO流对象

IO : Input Output IO作用是将数据从一个设备中流入到另一个设备。
数据文件,从磁盘中流向内存中 , 从磁盘中流向移动存储设备 , 从一台计算机流向另一台计算机。
一切都是字节 : 任何数据文件都是字节组成, 字节是计算机中最小的存储单元 (Java源码,游戏,音乐,电影)。
在这里插入图片描述

2 IO流对象的分类

2.1 按照操作的文件类型分类

文本类型文件 – 选择流对象字符流
什么是文本文件 : 使用文本工具,记事本,notepad++ ,editplus 打开文件后人类可以直接阅读
非文本类型文件 – 选择流对象字节流

2.2 按照数据的流向分类

输入流 : Java程序从其它地方读取数据
输出流 : Java程序中的数据,写入到其它地方

2.3 IO流对象的分类归纳

字节输出流 : OutputStream 抽象类
字节输入流 : InputStream 抽象类
字符输出流 : Writer 抽象类
字符输入流 : Reader 抽象类

3 字节输出流

java.io.OutputStream是所有字节输出流的超类 : 可以写入任何类型文件
写入字节的方法 write
void write(int b) 写入单个字节
void write(byte[] b)写入字节数组
void write(byte[] b,int off,int len) 写入数组的一部分,开始索引,写入的个数

3.1 FileOutputStream

构造方法 : FileOutputStream(File file)
构造方法 : FileOutputStream(String file)
创建字节输出流对象,绑定参数就是要写入的数据目的

JVM很聪明 : 任何一个操作系统都具备IO的能力, JVM依赖操作系统实现IO功能,IO流对象使用完毕后,要释放资源

3.2 字节输出流写入文件的步骤

创建字节输出流对象,构造方法中,绑定文件路径,写入目的
调用流对象的方法write写入数据
释放资源

public static void writeByteArray() throws IOException{
    //创建字节输出流对象 构造方法中,绑定文件路径,写入目的
    FileOutputStream fos = new FileOutputStream("D:/1.txt");
    byte[] bytes = {97,98,99,100};
    //写入字节数组
    fos.write(bytes);
    //写入字节数组中文
    fos.write("你好,我好,大家好".getBytes(StandardCharsets.UTF_8));
    //写入数组一部分
    fos.write(bytes,0,2);
    //释放资源
    fos.close();
}
public static void main(String[] args) throws IOException{
    //writeByte();
    writeByteArray();
}

3.3 追加写入和换行

追加写入, FileOutputStream构造方法的第二个参数写true
换行写入, 使用Windows系统的换行符号 \r\n

3.4 IO异常处理

 /**
     *  try catch异常处理 : close()写在finally
     */
    public static void write2()  {
        //提升作用域 : try外定义变量,try创建对象
        FileOutputStream fos = null;
        FileOutputStream fos2 = null;
        try {
            //创建字节输出流对象,构造方法中,绑定文件路径,写入目的
            fos = new FileOutputStream("c:/1.txt");
            fos2 = new FileOutputStream("c:/2.txt");
            //写入单个字节
            fos.write(45);
            fos.write(49);
            fos.write(48);
            fos.write(48);
        }catch (IOException ex){
            ex.printStackTrace();
        }finally {
            //释放资源
            try {
                //流对象创建失败,fos变量的值是空,不能调用close
                if(fos != null)
                    fos.close();
            }catch (IOException ex){
                ex.printStackTrace();
            }
            //释放资源
            try {
                //流对象创建失败,fos变量的值是空,不能调用close
                if(fos2 != null)
                    fos2.close();
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }

4 字节输入流

java.io.InputStream是所有字节输入流的超类 : 可以读取任何类型文件
读取字节的方法 read()
int read() 读取单个字节, 读取到流的末尾返回 -1
int read(byte[] b)读取字节数组 , 读取到流的末尾返回 -1

4.1 FileInputStream

构造方法 : FileInputStream(File file)
构造方法 : FileInputStream(String file)
创建字节输入流对象,绑定参数就是要读取的数据源文件

例如,读取字节数组:

public static void readByteArrary() throws IOException{
    FileInputStream fis = new FileInputStream("D:/1.txt");
    byte[] bytes = new byte[1024*5];  //字节数组推荐大小为1024的整数倍
    //定义一个变量 保存read方法的返回值
    int r = 0;
    //读取文件,传递字符数组
    while ((r=fis.read(bytes))!=-1){
        System.out.print(new String(bytes,0,r));
    }
   fis.close();
}

5 文件复制

实现文件的复制功能,操作系统中的Ctrl+C,Ctrl+V一样, 原理上就是字节搬家。

public static void copy_1() throws IOException {
    //字节流输入,绑定数据源文件
    FileInputStream fis = new FileInputStream("C:/Users/Acer/Pictures/Acer/p1.jpg");
   //字节流输出,绑定要复制的目的文件
    FileOutputStream fos = new FileOutputStream("D:/p1.jpg");
   //字节缓冲数组
    byte[] bytes = new byte[1024];
    //定义变量 保存读取方法read的返回值
    int r = 0;
    //循环读取数据源文件
    while ((r=fis.read(bytes))!=-1){
        //用字节输出流 写入字节数组 0索引开始,写入读取到的个数
        fos.write(bytes,0,r);
    }
     fis.close();
     fos.close();
}

6 字节流的缓冲流(更高效)

使用字节流的缓冲流,提高原有流对象的读写性能
字节流缓冲区流,流的本质上也是字节流
BufferedOuputStream 继承OutputStream
方法write() 写入单个的字节,或者字节数组
BufferedInputStream 继承InputStream
方法read()读取单个字节,读取字节数组

public static void copy_2() throws IOException{
    //字节流输入,绑定数据源文件
    FileInputStream fis = new FileInputStream("C:/Users/Acer/Pictures/Acer/p1.jpg");
    //字节流输出,绑定要复制的目的文件
    FileOutputStream fos = new FileOutputStream("D:/p1.jpg");
    //创建字节输入流的缓冲流,提高原有字节输入流的效率
    BufferedInputStream  bis = new BufferedInputStream(fis);
    //创建字节输出流的缓冲流 提高原有字节输出流的效率
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    //字节缓冲数组
    byte[] bytes = new byte[1024];
    //定义变量 保存读取方法read的返回值
    int r = 0;
    while ((r=bis.read(bytes))!=-1){
        bos.write(bytes,0,r);
    }
    //关闭流 当使用缓冲流的时候,只需要关闭缓冲流即可(缓冲流会自动关闭基础流)
    bis.close();
    bos.close();
}

7 字符流

只能操作文本文件
Writer类,是所有字符输出流的父类 (写入文本文件)
write(int c)写入单个字符
write(char[] ch)写入字符数组
write(char[] ch,int off,int len)写入字符数组一部分,开始索引,写入的个数
write(String str)写入字符串
void flush() 刷新该流的缓冲 (写入数据,先写入到内存), 只有刷新了数据才会到达目的文件
Reader类,是所有字符输入流的父类 (读取文本文件)
int read()读取单个字符
int read(char[] ch)读取字符数组

7.1 OutputStreamWriter类

OutputStreamWriter继承Writer,是字符的输出流,同时又是转换流
字符流 = 字节流 + 编码表
OutputStreamWriter 转换流 : 字符流通向字节流的桥梁, 字符转成字节
构造方法:
OutputStreamWriter(OutputStream out)传递任意字节输出流
OutputStreamWriter(OutputStream out,String 编码表名)传递任意字节输出流
转换流写入字符文件,UTF-8编码

7.2 InputStreamReader

InputStreamReader继承Reader,字符输入流,读取文本文件
字节流通向字符流的桥梁, 字节流转成了字符流
构造方法:
InputStreamReader(InputStream out)传递任意字节输入流
InputStreamReader(InputStream out,String 编码表名)传递任意字节输入流

7.3 便捷类

FileWriter 继承 OutputStreamWriter
是字符的输出流,写入文本文件
直接采用默认的编码表
FileWriter构造方法直接传递字符串的文件名即可

FileReader 继承 InputStreamReader
是字符的输入流,读取文本文件
直接采用默认的编码表
FileReader构造方法直接传递字符串的文件名即可

7.4 字符输出流的缓冲流

BufferedWriter : 字符流的缓冲流,继承Writer,写入文本文件
特殊的方法 : newLine() 写入文本换行符,平台无关性
构造方法: BufferedWriter(Writer w)可以传递任意字符输出流

7.5 字符输入流的缓冲流

BufferedReader : 字符流的缓冲流,继承Reader,读取文本文件
特殊的方法 :String readLine() 读取文本一行,平台无关性
构造方法: BufferedReader (Reader r)可以传递任意字符输入流

8 打印流

PrintStream : 字节输出流
PrintWriter : 字符输出流
打印流特性 :
打印流负责输出打印,不关心数据源
方便的打印各种形式数据
打印流永远不会抛出IOException
具有自动刷新

9 对象的序列化

对象的序列化的意义 : 对象变成一个文件,在网络中传递,可以让任何一个人使用。
在这里插入图片描述
ObjectOutputStream 对象的序列化
构造方法ObjectOutputStream(OutputStream out)传递字节输出流
void writeObject(Object o)写入对象

/**
 * @author summer
 * @date 2021/12/8 15:27
 * @Description  实现接口,启用序列化
 */
public class Person implements Serializable {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public static void writeObj() throws IOException {
    //创建字节输出流,绑定文件
    FileOutputStream fos = new FileOutputStream("D:/person.txt");
    //对象的序列化流创建
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    //oos流,写入对象
    Person p = new Person("张三",20);
    oos.writeObject(p);
    oos.close();
}

ObjectInputStream 对象的反序列化
构造方法ObjectInputStream (InputStream out)传递字节输入流
Object readObject()读取对象

/**
 * 对象的反序列化
 */
public static void readObj() throws Exception{
    //创建字节输入流,读取数据文件,源文件必须是序列化后的文件
    FileInputStream fis = new FileInputStream("D:/person.txt");
    //创建反序列化对象
    ObjectInputStream ois = new ObjectInputStream(fis);
    //读取对象
    Object object = ois.readObject();
    System.out.println(object);
    ois.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值