Java--IO流

一、IO

1.1 简介:

1.I==>Input  输入   Output 输出   用于不通过设备进行信息的交互
2.使用的场景:
    A.文件的复制
    B.文件上传的下载
    C.(即时通信)微信中信息的传递
3.IO 分类
   流向划分:输入流与输出流
   类型划分:字节流与字符流
4.输入流与输出流的解释
5.字节流与字符流的解释
  字节流:
     A.万物皆字节  系统上任何的资源都可以使用字节来进行表示  
     B.一般读写文件 音视频 图片
     C.分类:字节输入流(读)   字节输出流(写)
  字符流:  
      A.字符流=字节流+编码表 字符流的底层也是使用字节流来进行操作的  只能底层通过编码表将字节转换为字符
      B.读取纯字符的文件 
      C.分类:字符输入流(读) 与字符输出流(写)
6.IO操作的注意点:
   A.所有的流的资源都是java.io包下
   B.使用流资源的时候 可能会产生异常 需要对异常处理(捕获 抛出)
   C.所有的流资源使用之后 必须进行关闭 因为流资源比较消耗内存

1.2 OutputStream

1.2.1 简介

此抽象类是表示输出字节流的所有类的超类

  • OUtputStream 是一个抽象类

  • OutputStream输出字节流的所有类的超类

1.2.2 常用的方法
方法的名称方法的描述
public abstract void write(int b)一个一个字节写入
public void write(byte[] b)将字节数组的内容写入
public void write(byte[] b, int off, int len)将字节数组的指定的长度的内容写入
public void flush()将缓冲区的数据刷新到硬盘中
public void close()关闭流资源

1.3 FileOutputStream

1.3.1 简介
  • 文件字节输出流是用于将数据写入 File 将数据写入到文件中
  • FileOutputStream 用于写入诸如图像数据之类的原始字节的流
  • 要写入字符流,请考虑使用 FileWriter
1.3.2 使用步骤

A例化FileOutputStream
B.调用写的方法
C.关闭资源

1.3.3 使用字节流写字符串到文件中
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Test01 {
    public static void main(String[] args) throws IOException {
        //实例化FileOutputStream
        OutputStream os  =new FileOutputStream("d:\\a\\4.txt",true);//true末尾追加
        String s="阿豪牛牛牛";
        //将字符串转换为字节数组
        byte[] b = s.getBytes();
        os.write(b);
        os.close();
    }
}
1.3.4 说明

问题: 写入的字节是 97 98 99 使用记事本打开就是 a b c
原因: 记事本打开的文件的时候 如果字节的范围是 0-127 使用ASCII表来识别
超出范围 使用的记事本默认的码表来识别 默认的码表就是GBK

1.4 InputStream

1.4.1 简介
  1. 此抽象类是表示字节输入流的所有类的超类
  2. InputStream 是一个抽象类
  3. InputStream是输入流的所有类的超类
1.4.2 常用的方法
方法 的名称方法的描述
public void close()关闭资源
public abstract int read()一个一个字节读取
public int read(byte[] b)将读取的内容存入到缓冲数组中
public int read(byte[] b, int off, int len)读取指定长度的内容存入缓冲数组中

1.5 FileInputStream

1.5.1简介
  • FileInputStream 用于来读取文件中的内容
  • FileInputStream 用于读取诸如图像数据之类的原始字节流 用于操作字节
  • 要读取字符流,请考虑使用 FileReader
1.5.2 使用步骤

A.实例化FileInputStream
B.调用读取的方法
C.关闭流资源

1.5.3 一次读取多个字节
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test02 {
    public static void main(String[] args) throws IOException {
        InputStream is  = new FileInputStream("d:\\a\\1.txt");
        //定义缓存区的数组
        byte [] b  = new byte[1024];
        int length=-1;
        while ((length=is.read(b)) !=-1){
            System.out.println(new String(b,0,length));
        }
        //关闭资源
        is.close();


    }
}
1.5.4 read() 与 read(b)比较
A.read() 一个一个字节读  效率低   read(b) 一次读取多个字节放入到数组  效率高
B.read() 返回值是读取的字节       read(b) 返回值是读取的有效的字节的个数 

1.6 文件复制

代码:

import java.io.*;

public class Test05 {
    public static void main(String[] args) throws IOException {
        //实例化输入流
        InputStream is  = new FileInputStream("d:\\a\\1.jpg");
        //实例化输出流
        OutputStream  os  = new FileOutputStream("c:\\admin\\1.jpg");
        byte [] b  = new byte[1024];
        int length =-1;
        while ((length =is.read(b)) !=-1) {
            os.write(b,0,length);
        }
        //关闭资源
         os.close();
         is.close();
    }
}

1.7 高效流

1.7.1 读写视频案例
import java.io.*;

public class Test01 {
    public static void main(String[] args) {
        OutputStream os = null;
        BufferedOutputStream bos = null;
        InputStream is = null;
        BufferedInputStream bis = null;
        try {
            os = new FileOutputStream("d:\\a\\1.mp4");
            bos =new BufferedOutputStream(os);
            is =new FileInputStream("E:\\IO\\a.mp4");
            bis =new BufferedInputStream(is);
            int length = -1;
            while ((length = bis.read()) != -1) {
                bos.write(length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (bos !=null){
                    bos.close();
                }

                if (bis !=null){
                    bis.close();
                }
                if (is !=null ){
                    is.close();
                }
                if (os !=null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

1.8 关闭资源

  1. 从下往上进行关闭(最后的使用先关闭)
  2. 不管是否发生异常 都会要关闭io流资源 在finally中关闭流资源
  3. 关闭流资源 需要进行非空验证

二、字符流

2.1 简介

1.字符流:用于读写字符
2.分类:字符输入流(读)  字符输出流(写)
3.使用字符流原因:
    使用字节流读取字符 需要将读取的内容来进行转换,转换错误可能会出现乱码  使用字节操作字符比较麻烦
    字符流=字节流+编码表
4.任何的编码表下 中文的第一个字节都是负数  根据这个规律来进行转换

2.2 字符流-写Witer

  1. Writer 写入字符流的抽象类
  2. 子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。
  3. 多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能

2.3 FileWriter

2.3.1 简介
  1. 用来写入字符文件的便捷类

  2. 可以先在 FileOutputStream 上构造一个 OutputStreamWriter 设置编码表格式

  3. FileWriter 用于写入字符流。要写入原始字节流,请考虑使用 FileOutputStream。

2.3.2 构造方法
方法的名称方法的描述
public FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象
public FileWriter(File file, boolean append)根据给定的 File 对象构造一个 FileWriter 对象。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处
public FileWriter(String fileName)根据给定的文件名构造一个 FileWriter 对象
public FileWriter(String fileName, boolean append)根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象

代码—写:

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Test01 {
    public static void main(String[] args) throws IOException {
        Writer w  = new FileWriter("1.txt");
        w.write(97);
        w.write(new char[]{'b','c'});
        w.write("今天天气真好!适合学习java");
        w.close();
    }
}

3.4 字符流-读 Reader

3.4.1 简介
  1. 用于读取字符流的抽象类
  2. 子类必须实现的方法只有 read(char[], int, int)
  3. 多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能
3.4.2 字符流-读

代码:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Test02 {
    public static void main(String[] args) throws IOException {
        Reader  r  = new FileReader("1.txt");
        char [] ch = new char[1024];
        int length=-1;
        while ((length =r.read(ch)) !=-1) {
            System.out.println(new String(ch,0,length));
        }
        //关闭资源
        r.close();
    }
}

3.5 注意点

A.不能使用字符流来读取音视频以及图片

B. 原因:因为使用字符流读取文件的时候 需要依赖于编码表来进行转换

​ 音视频 不能使用常规编码表来进行转换

三、 转换流

3.1 InputStreamReader-简介

  1. InputStreamReader 是字节流通向字符流的桥梁
  2. 它使用指定的 charset 读取字节并将其解码为字符 可以设置其编码的格式
  3. 为了达到最高效率,可要考虑在 BufferedReader

3.2 InputStreamReader 读

import java.io.*;

public class Test01 {
    public static void main(String[] args) throws IOException {
        InputStream is  = new FileInputStream("1.txt");
        InputStreamReader  isr = new InputStreamReader(is,"UTF-8");
        int leng =-1;
        //byte [] b = new byte[1024];

        while ((leng =isr.read()) !=-1){
            System.out.println((char) leng);
        }
    }
}

3.3 OutputStreamWriter-简介

  1. OutputStreamWriter 是字符流通向字节流的桥梁
  2. 使用指定的 charset 将要写入流中的字符编码成字节 可以设置其编码表
  3. 为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中

3.4 OutputStreamWriter 写

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

public class Test02 {
    public static void main(String[] args) throws IOException {
        OutputStream os = new FileOutputStream("3.txt");
        OutputStreamWriter  osw  = new OutputStreamWriter(os,"GBK");
        osw.write("哈哈哈今天又到星期一");
        osw.close();
        os.close();
    }
}

四、字符的高效流

4.1 高效流-读-BufferedReader 简介

  1. 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
  2. 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了

4.2 BufferedReader-读

import java.io.*;

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

//        Reader  r  = new FileReader("1.txt");
      /*  InputStream is =  new FileInputStream("1.txt");
        InputStreamReader  in  = new InputStreamReader(is,"Utf-8");
        BufferedReader  br   = new BufferedReader(in);*/
         BufferedReader br  = new BufferedReader(new InputStreamReader(new FileInputStream("1.txt"),"UTF-8"));
        String  line=null;
        while ((line = br.readLine()) !=null){
            System.out.println(line);
        }
        br.close();
//        in.close();
//        is.close();

    }
}
4.3 高效流-写 BufferedWriter简介
  1. 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写
  2. 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
  3. 该类提供了 newLine() 方法 表示换行

4.4 BufferedWriter-写

import java.io.*;

public class Test02 {
    public static void main(String[] args) throws IOException {
      /*  Writer w = new FileWriter("4.txt");
        BufferedWriter  bw  = new BufferedWriter(w);*/
      BufferedWriter  bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("6.txt"),"UTF-8"));
        bw.write("詹姆斯完爆勇士");
        bw.newLine();
        bw.write("蓝网阿杜回顾");
        //刷新的方法
       // bw.flush();
        bw.close();
//        w.close();
    }
}
4.5 close() 与flush()的比较
  1. flush() 将缓冲区的数据刷新到硬盘中
  2. close() 关闭流资源
    close() 方法的底层会调用flush()方法
  3. 区别:
    调用 close() 方法之后 流资源就不能使用
    调用 flush() 方法之后 流资源是可以使用

五、对象流

5.1 序列化与反序列化

1.使用场景:将读写存储的文件的时候  或者是在网络通信传输对象的时候 就需要使用序列化(读写文件中的对象)
要被序列化的对象,类需要实现Serializable接口
2.序列化机制:使用一个序列化的字节(唯一的标识) 来表示文件中的对象(属性值  以及方法)
3.序列化:将对象写入到文件中的过程 就是序列化  将对象进行流化 加快对象写入到文件的速度
4.反序列化:将文件的序列化的对象 读取的过程 就是反序列化 加快读取的速度
5.2 案例
import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        //序列化
        OutputStream os = new FileOutputStream("src\\4.txt");
        ObjectOutputStream oos = new ObjectOutputStream(os);

        ArrayList<Student> list = new ArrayList<>();
//        oos.writeObject(new Student("张三",18));
//        oos.writeObject(new Student("李四",19));
        Student stu1 = new Student("张三", 18);
        Student stu2 = new Student("李四", 19);
        Student stu3 = new Student("王五", 20);

        list.add(stu1);
        list.add(stu2);
        list.add(stu3);

        oos.writeObject(list);
        oos.flush();

        oos.close();
        os.close();

        //反序列化
        FileInputStream fis = new FileInputStream("src\\4.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);

        List<Student> list1 = (ArrayList) ois.readObject();

        list1.forEach(student -> System.out.println(student));

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值