java进阶基础---2.3---IO流的概念及示例

小梁同学 の

Java学习旅途

你好! 这是小梁同学使用 博客 所记录的文章笔记,作为一个初学者的从基础到未来的记录,如果你想和我一起在Java学习路程上坚持下去,欢迎你的关注与指正。

以下所有有关代码,都是个人在上完课后自己重新敲代码之后所做笔记后上传,并非原搬直接上传,谢谢理解

三.IO流

1.IO流分类

1.概念

I/O: input(输入) /Output(输出)

流: 抽象概念,数据传输的总称,就是说数据在设备之间的传输称之为流,本质就是传输

常见的数据传输形式: 文件的Copy、上传、下载

2.根据数据流向分类

输入流: 读数据

输出流: 写数据

解释: 站在内存的角度考虑

3.根据数据类型分类

字节流(万能流): 字节输入流 / 字节输出流

字符流 : 字符输入流 / 字符输出流

2.字节流

1.字节流写数据

字节输出流–OutputStream

方法名说明
FileOutputStream(String name)根据参数指定的路径名来构造对象并关联起来。
FileOutputStream(String name,boolean append)以追加的方式构造对象
void write(int b)用于将参数指定的单个字节写入输出流
void write(byte[] b)用于将参数指定的字节数组内容全部写入到输出流中
void write(byte[] b,int off,int len)用于将数组中的一部分内容写入到输出流中
void close()关闭输出流并释放资源

直接创建的话会显示OutputStream抽象类不能够实例化对象,故选择它的子类FileOutputStream创建字节输出流对象,代码如下:

在这里插入图片描述

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

public class Test1 {
    public static void main(String[] args) throws IOException {
        //抽象类不能够实例化对象
//      OutputStreamtream outputStream = new OutputStream();

//      1.创建字节输出流对象
//(1)覆盖写,每次重新运行程序都会在创建的文本中重新写入数据
        FileOutputStream fops = new FileOutputStream("./myBook.txt");  
//(2)追加写,通过构造方法中的第二个参数来决定
		//true,则在原文本后面加上新写入的
		//false,则表示不追加写,与覆盖写异曲同工
		FileOutputStream fops = new FileOutputStream("./myBook.txt"true); 

        //2.数据的传输操作
//(1)正常一个一个写入
        fops.write(68);//'D'
		fops.write(69);//'E'
//(2)向文件中写入26个英文字母
        for (int i = 0; i < 26; i++) {
            fops.write(65 + i);
        }
//(3)写一个byte数组
		byte[] bytes = {97,98,99,100,101,102};
		fops.write(bytes);//'abcdef'
//(4)将一个字符串转换未byte类型数组,getBytes()
		byte[] bytes = "187288837298你好,小白".getBytes();
		//第一个参数为起始点,后一个为截止长度
        fops.write(bytes,0,16);

        //3.关闭流,释放资源
        fops.close();
    }
}
2.字节流读数据

字节输入流-- InputStream

方法名说明
FileInputStream(File file)根据参数指定File类对象创建字节输入流对象
FileInputStream(String name)根据参数指定的路径名来构造对象并关联起来
int read()用于从输入流中读取单个字节的数据
int read(byte[] b)用于从输入流中读取数组长度个字节的数据
int read(byte[]b,int off, int len)用于从输入流读取数组中一部分内容
void close()关闭输入流并释放资源

与字节输出流一样,直接创建的话会显示InputStream抽象类不能够实例化对象,故选择它的子类FileInputStream创建字节输出流对象,代码如下:

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

public class Test2 {
    public static void main(String[] args) throws IOException {
//1.创建字节输入流对象
        FileInputStream fips = new FileInputStream("./myBook.txt");
//2.操作输入流数据
        //(1)一次读一个字节
//        int by = fips.read();
//        by = fips.read();
//        by = fips.read();
//        System.out.println(by);//当没有数字时,by会输出-1.

        //(2)单个字节循环读取
//        int by;
//        while ((by = fips.read())!=-1){
//        System.out.println((char)by);
//        }

        //(3)一次读取一个数组
        byte[] bytes = new byte[10];//用来读取数据的缓冲区
        int len = fips.read(bytes);//返回的是数组中实际数据的长度
        System.out.println(new String(bytes));
        System.out.println(new String(bytes,0,len));

        //(4)通过数组循环的方式读取数据
        //将数据读取到byte数组中时,如果有数据则返回实际数据的长度,如果没有数据,则返回-1
        while ((len=fips.read(bytes))!=-1) {
            System.out.println(new String(bytes));
            System.out.println(new String(bytes, 0, len));
        }

//3.关闭连接并释放资源
        fips.close();
    }
}
3.字节流异常处理
  • 抛出 或者 捕获
  • 通过finally来释放资源close

字节流中异常处理可以通过抛出或捕获的方式进行处理,但不推荐捕获,因为相对于抛出而言,捕获的代码不易规整,以下代码为捕获处理异常,仅供参考:

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

public class Test1 {
    public static void main(String[] args)  {
        //1、创建字节输出流对象
        FileOutputStream fops = null; //覆盖写
        try {
            fops = new FileOutputStream("./myBook.txt");
//          2、数据的传输操作
            byte[] bytes = "1872367882你好小白".getBytes();//将字符串转换成byte类型数组
            fops.write(bytes,0,22);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
//        3、关闭流,释放资源
            try {
                fops.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
4.字节流(边读边写)

读一个字节,写一个字节

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class test3 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fips = new FileInputStream("./myTest.txt");
        //创建字节输出流对象
        FileOutputStream fops = new FileOutputStream("./newMyTest.txt");
        int by;
        while ((by = fips.read())!=-1){//读一个字节同时写一个字节
            fops.write(by);
        }
        //关闭流,释放资源
        fips.close();
        fops.close();
    }
}
5.字节流缓冲区
  • BufferedOutputStream
  • BufferedInputStream

分别定义四个方法来进行对比看所复制文件的时间:
基本字节流一次读写一个字节
基本字节流一次读写一个数组
缓冲区字节流一次读写一个字节
缓冲区字节流一次读写一个数组

import java.io.*;
public class Test3 {
    public static void main(String[] args) throws IOException{
        final String VCR = "./video.mp4";
        final String TO = "./newVideo.mp4";

        long startTime = System.currentTimeMillis();//开始时的毫秒数
        method1(VCR,TO);
        //method2(VCR,TO);
        //method3(VCR,TO);
        //method4(VCR,TO);

        long endTime = System.currentTimeMillis();//结束时的毫秒数
        System.out.println("复制该文件共耗时:"+(endTime - startTime)+"毫秒");
    }
    //定义method1方法:基本字节流一次读写一个字节,实现文件Copy
    private static void method1(String vcr, String to) throws IOException {
        //1.创建字节流对象
        FileInputStream fips = new FileInputStream(vcr);
        FileOutputStream fops = new FileOutputStream(to);
        //2.操作字节流数据
        int by;
        while ((by = fips.read())!=-1){
            fops.write(by);
        }
        //3.关闭连接并释放资源
        fips.close();
        fops.close();
    }

    //定义method2方法:基本字节流一次读写一个数组,实现文件Copy
    private static void method2(String vcr, String to) throws IOException {
        //1.创建字节流对象
        FileInputStream fips = new FileInputStream(vcr);
        FileOutputStream fops = new FileOutputStream(to);
        //2.操作字节流数据
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fips.read(bytes))!=-1){
            fops.write(bytes,0,len);
        }
        //3.关闭连接并释放资源
        fips.close();
        fops.close();
    }

    //定义method3方法:缓冲区字节流一次读写一个字节,实现文件Copy
    private static void method3(String vcr, String to) throws IOException {
        //1.创建字节流对象
        BufferedInputStream bips = new BufferedInputStream(new FileInputStream(vcr));
        BufferedOutputStream bops = new BufferedOutputStream(new FileOutputStream(to));
        //2.操作字节流数据
        int by;
        while ((by = bips.read())!=-1){
            bops.write(by);
        }
        //3.关闭连接并释放资源
        bips.close();
        bops.close();
    }

    //定义method4方法:缓冲区字节流一次读写一个数组,实现文件Copy
    private static void method4(String vcr, String to) throws IOException {
        //1.创建字节流对象
        BufferedInputStream bips = new BufferedInputStream(new FileInputStream(vcr));
        BufferedOutputStream bops = new BufferedOutputStream(new FileOutputStream(to));
        //2.操作字节流数据
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bips.read(bytes))!=-1){
            bops.write(bytes,0,len);
        }
        //3.关闭连接并释放资源
        bips.close();
        bops.close();
    }
}

3.字符流

1.概述

存储形式: 一个英文、汉字以及标点符号的存储就是其对应的简单字符

字符流 = 字节流 + 编码表

常见的字符编码:

①ASCll

②GBK

③Unicode

④UTF-8/16/32

2.编码与解码
  • 编码
    • getBytes():使用平台默认的编码格式(字符集)
    • getBytes(Stirng chatSetName) : 使用的是指定的编码格式(字符集)
  • 解码
    • String(byte[] bytes) : 使用平台默认的编码格式解码(字符集)
    • String(byte[] bytes,String charSetName) : 使用指定的编码格式解码(字符集)
package com.liang.IO03;
import java.util.Arrays;
import java.io.UnsupportedEncodingException;
public class Test04 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = "Jack梁";
        //使用UTF-8字符集进行编码
        byte[] byte1 = str.getBytes("UTF-8");
        //使用GBK字符集进行编码
        byte[] byte2 = str.getBytes("GBK");
        //不规定的情况下使用的是平台默认的编码格式
        byte[] byte3 = str.getBytes();
        System.out.println(Arrays.toString(byte1));
        System.out.println(Arrays.toString(byte2));
        System.out.println(Arrays.toString(byte3));
        
        //平台默认的编码格式解码
        System.out.println(new String(byte3));
        //指定的编码格式解码
        //因为字符集不同,所以中文出现乱码
        System.out.println(new String(byte3,"GBK"));
    }
}
===========================
    [74, 97, 99, 107, -26, -94, -127]
	[74, 97, 99, 107, -63, -70]
	[74, 97, 99, 107, -26, -94, -127]
    JackJack姊�
3.字符流写数据

OutputStreamWriter

package com.liang.IO03;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;


public class Test05 {
    public static void main(String[] args) throws IOException {
        //将字节输出流对象包装成字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("./muTest.txt",false));

        //写一个字符
        osw.write(66);
        osw.write('d');

        //写一个字符串
        osw.write("你好,李焕英!");
        osw.write("987654321",4,3);

        //写一个字符数组
        char[] chars={'a','s','d','f','g'};
        osw.write(chars);
        osw.write(chars,3,2);

        //关闭流
        osw.close();
    }
}
4.字符流读数据

InputStreamReader

package com.liang.IO03;

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

public class Test06 {
    public static void main(String[] args) throws IOException {
        //将字节输入流对象包装成字符输入流对象
        InputStreamReader isr = new InputStreamReader(
                new FileInputStream("./muTest.txt"));

        //一次读取一个字符
//        int is;
//        while ((is = isr.read()) != -1){
//            System.out.println((char)is);
//        }

        //一次读一个字符数组
        char[] chars = new char[1024];
        int len;
        while ((len =isr.read(chars)) != -1){
            System.out.println(chars);
        }

        //关闭流
        isr.close();
    }
}
5.字符流的文本拷贝
package com.liang.IO03;
import java.io.*;

public class Test07 {
    public static void main(String[] args) throws IOException {
        将字节输出、输入流对象包装成字符输出、输入流对象
        //字符流构造方法中的第二个参数用来设置字符集(编码格式)
        InputStreamReader isr = new InputStreamReader(
                new FileInputStream("./muTest.txt"), "GBK");
        OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("./myTest.txt"),"GBK");

        //单个字符形式
        int is ;
        while ((is = isr.read()) != -1){
            osw.write(is);
        }

        //单个字符数组形式
        char[] chars = new char[1024];
        int len;
        while ((len = isr.read(chars)) != -1){
            osw.write(chars,0,len);
        }

        //关闭流
        isr.close();
        osw.close();
    }
}

6.字符流的简化写法
  • FileReader
  • FileWriter
package com.liang.IO03;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test08 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("./muTest.txt");
        FileWriter fw = new FileWriter("./newMuTest.test");

        //一次读写一个字符
        int is;
        while ((is = fr.read()) != -1){
            fw.write(is);
        }

        //一次读写一个字符数组
        char[] chars = new char[1024];
        int len;
        while ((len = fr.read(chars)) != -1){
            fw.write(chars,0,len);
        }

        fr.close();
        fw.close();
    }
}

7.字符流缓冲区
1.高效读写
  • BufferedReader
  • BufferedWriter
public class Test09 {
    public static void main(String[] args) throws IOException {
        //创建缓冲区字符流对象
//        BufferedReader br = new BufferedReader(
//                new InputStreamReader(new FileInputStream("./muTest.txt")));
//        BufferedWriter bw = new BufferedWriter(
//                new OutputStreamWriter(new FileOutputStream("./myNewTest.txt")));
        //简写创建缓冲区字符流对象
        BufferedReader br = new BufferedReader(
                new FileReader("./muTest.txt"));
        BufferedWriter bw = new BufferedWriter(
                new FileWriter("./myNewTest.txt"));

        //实现文本文件复制
        char[] chars = new char[1024];
        int len;
        while ((len = br.read(chars)) != -1){
            bw.write(chars,0,len);
        }

        //关闭流
        br.close();
        bw.close();
    }
}
2.特有方法
数据流向方法含义
BufferedWritervoid newLine()插入新的换行符
BufferedWritervoid flush()刷新输出流
BufferedReaderString readLine()读取一行,读到没有则返回null
public class Test10 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("./muTest.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("./muNewTest.txt"));

        //将读出来的一行字符串存入到line中
        String line;
        //判断行是否为空
        while ((line = br.readLine()) != null){
            //写一行
            bw.write(line);
            //换一行,插入一个换行符
            bw.newLine();
            //手动刷新
            bw.flush();
        }

        br.close();
        bw.close();
    }
}

4.标准流

1.System.in标准输入流

获取标准设备输入的流

public class Test11 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new FileWriter("./myNewTest.txt"));

        //向程序中输入内容,直到over出现程序终止
        String str;
        System.out.println("请输入一行字符串:");
        while (true){
            //判断输入的内容是不是over
            if ((str = br.readLine()).equals("over")){
                //出现over 则结束后跳出循环
                System.out.println("聊天结束!");
                break;
            }
            //程序没有结束时写入一行
            bw.write(str);
            //进行换行继续写入
            bw.newLine();
            //实时刷新
            bw.flush();
        }

        br.close();
        bw.close();
    }
}
=========================
    请输入一行字符串:
	sdfbgb265
	5451516
	edrg516656415
	454
	rgrfgwef
	over
	聊天结束!
2.System.out标准输出流

将数据显示到标准输出设备中

public class Test12 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(System.out));

        bw.write("标准输出流");
        System.out.println("正常打印");
        bw.close();
    }
}
3.System.err 标准错误流
public class Test13 {
    public static void main(String[] args) throws IOException {
        System.out.println("正常输出");
        //标准错误流:显示颜色红色,不建议与自己封装的错误流同时使用
        //System.err.println("我是标准错误流");
        //自己封装的错误流
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(System.err));
        bw.write("自定义封装的错误流");
        bw.close();
    }
}

5.对象的持久化存储

1.单个学生对象存储到文件
public class Student {
    private String name;
    private int 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;
    }

    public Student() {
    }

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

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

public class Demo01 {
    public static void main(String[] args) throws IOException {
        Student stu = new Student("Jack", 18);
//        mySave(stu);
        Student resStu = myLoad();
        System.out.println(resStu);
    }

    private static Student myLoad() throws IOException {
        //读文件
        BufferedReader br = new BufferedReader(new FileReader("./myTest.txt"));

        String str = br.readLine();
        String[] split = str.split("##");
        Student stu = new Student(split[0], Integer.parseInt(split[1]));

        br.close();
        return stu;
    }

    private static void mySave(Student stu) throws IOException {
        //将其写到文件中
        BufferedWriter bw = new BufferedWriter(new FileWriter("./myTest.txt"));
        bw.write(stu.getName() + "##" + stu.getAge());
        bw.close();
    }
}
2.多个学生对象存储到文件
public class Demo02 {
    public static void main(String[] args) throws IOException {
        Student[] students = new Student[8];
        students[0] = new Student("张三", 28);
        students[1] = new Student("李四", 26);
        students[2] = new Student("王五", 22);
        students[3] = new Student("赵六", 27);
        students[4] = new Student("贾七", 24);
        students[5] = new Student("魏八", 25);
        students[6] = new Student("孙九", 29);
        students[7] = new Student("老大", 30);
        //将多个对象存储到文件中
        //saveStu(students);
        //读取文件内容
        Student[] stud = loadStu();
        for (Student stu :stud) {
            System.out.println(stu);
        }
    }

    private static Student[] loadStu() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("./myTest.txt"));
        //获取每一条学生信息
        String[] stuArr = br.readLine().split("@@");
        //存储从文件中取出来的学生信息对象
        Student[] students = new Student[8];
        for (int i = 0;i<students.length;i++){
            String[] stus = stuArr[i].split("##");
            students[i] = new Student(stus[0],Integer.parseInt(stus[1]));
        }

        br.close();
        return students;
    }

    private static void saveStu(Student[] students) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("./myTest.txt"));
        //遍历数组拿到对象
        for (Student stu:students) {
            bw.write(stu.getName() + "##" + stu.getAge() + "@@");
        }
        bw.close();
    }
}
3.对象的串行化(序列化)操作
  • ObjectOutputStream
  • ObjectInputStream
public class Student implements Serializable {
    private String name;
    private int age;
    private static final long serialVersionUID = -5281125824123725016L;
    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;
    }
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void show(){
        System.out.println("zhanshi ");
    }
}
public class Demo03 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //序列化存单个对象
//        Student stu = new Student("Jack", 50);
//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myTest.txt"));
//        oos.writeObject(stu);
//        oos.close();
        //序列化取单个对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myTest.txt"));
        Student student = (Student) ois.readObject();
        System.out.println(student);
        ois.close();
    }
}

注:

​ 1.实体类序列化(串行化)后,不可以改变类中方法,否则报错

​ 解决方式:找到序列化编号,在实体中定义常量

private static final long serialVersionUID = -5281125824123725016L;

​ 2.屏蔽序列化:transient

java进阶基础—2.2----上一章节: File类

java进阶基础—课后习题: 跳转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值