Bootstrap

java基础入门学习07-IO流

一、引言

在程序中我们常常会需要从外部获取数据或者向外部写入数据,这个过程也就是写入写出(Input Output)那么流其实是一个抽象的概念,其实是数据传输的通道,你也可以把数据流当作水流。

二、IO流分类

2.1 四大IO流抽象类

在java中IO流通常继承于四种抽象类,这四种抽象类可以再仔细划分为两大类
一、字节流

  • InputStream字节输入流
  • OutputStream字节输出流

二 、字符流

  • Reader字符输入流
  • Writer字符输出流

2.2 字节流用法

1、文件字节输入输出流

java中读取和写出数据的类分别是FileInputStream和FileOutputStream
首先来讲FileInputStream,该类的读取关键方法是read(),该方法如果读取到内容会返回字节数值0~255,,若是读取完毕则会返回-1,这就是我们判断读取完毕的关键,然后读取完毕后我们还需要注意的是需要关闭流以释放资源。

public class IOTest1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\1.txt");
        //2. 循环逐个读取字节
        int sum=0;
        StringBuilder sb = new StringBuilder();
        while ((sum=fis.read())!=-1)//如果文件中的字节读取完毕,则返回-1,否则返回该字节数值(0-255)
            sb.append((char)sum);
        System.out.println(sb.toString());
        //3. 关闭流
        fis.close();
    }
}

至于OutputStream中的关键方法是write(),可以搭配着InputStream来完成文件内容的复制,但需要注意的一个点是我们需要把通道中剩余的内容写入后才能关闭通道,需要使用flush()方法。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOTest1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:/1.txt");
        FileOutputStream fos = new FileOutputStream("D:/2.txt");
        int temp=0;
        while ((temp=fis.read())!=-1)
        {
            fos.write(temp);
        }
        fos.flush();
        fis.close();
        fos.close();
    }
}

2、缓冲字节流

一个一个字节读取效率未免过低,在此基础上,又衍生出了缓冲区写法,生成一个缓冲区来读取,举例对上述代码改造,

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOTest1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:/1.txt");
        FileOutputStream fos = new FileOutputStream("D:/2.txt");
        int temp=0;
        byte[] buffer = new byte[1024];
        while ((temp=fis.read(buffer))!=-1)
        {
        	// 第二个参数代表起始偏移量,第三个参数代表的是写入数据的最大长度
            fos.write(buffer,0,temp);
        }
        fos.flush();
        fis.close();
        fos.close();
    }
}

在此基础上就直接产生了BufferedInputStream和BufferedOutputStream,这种类对象可以省去参数,创建此类对象需要把InpustStream和OutputStream对象做参数来构造。

import java.io.*;

public class IOTest1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:/1.txt");
        FileOutputStream fos = new FileOutputStream("D:/2.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int temp=0;
        while ((temp=bis.read())!=-1)
        {
            bos.write(temp);
        }
        bos.flush();
        bos.close();
        bos.close();
    }
}

3、数据流

DataInputStream和DataOutputStream将基本数据类型的数据以字节流形式输入输出到本地文件,但是它只能对基本数据类型进行操作。

DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/data")));

数据流对象的创建需要把缓冲流作为参数
数据流的使用方式就是根据写的基本类型来使用对应方法

//write后面跟随数据基本类型
dos.writeChar('test');
dos.writeBoolean(false);
dos.writeDouble(Math.random());
//read后面跟随数据基本类型
dis。readChar()
dis.readInt()

4、序列化字节流

首先需要理解什么是序列化,本质上就是将程序内存中的任何数据以二进制文件的形式进行保存,我们可以把自己编写的对象序列化以后通过网络传输,这就是序列化流存在的意义。反序列化就是将二进制文件恢复为对象数据的过程。

ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("D:/data1")));
oos.writeObject(user);
(User)ois.readObject()

ObjectInputStream和ObjectOutputStream对象创建都需要缓冲流对象做参数,这一点跟DataInputStream一致,也可以认为Data流就是不能转换自定义对象的Object流

2.3 字符流

1、FileWriter与FileReader

学习了上述的字节流以后其实字符流的区别不大,字符流就是将数据以字符单位写入文件基本的有FileWriter和FileReader

 public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:/2.txt"true);
        fw.write("test");
        fw.flush();
        fw.close();
    }

在字符流中的第二个方法使用于判断是否需要追加,如果不添加true默认是覆盖原有文件。
FileReader用法同FileInputStream一致不再赘述

2、缓冲字符流

BufferedReader类及BufferedWriter类两个处理流,实现缓冲区


public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:/1.txt");
        BufferedWriter bw= new BufferedWriter(fw);
        bw.write("test");
        bw.flush();
        bw.close();
        fw.close();
    }
    
public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("D:/1.txt");
        BufferedReader br = new BufferedReader(fr);
        String temp="";
        while ((temp=br.readLine())!=null)
            System.out.println(temp);
        br.close();
        fr.close();
    }

区别在于读取时BufferedReader的读取方法为readLine()而不是read()

3、转换流

System.in和System.out返回的都是字节流对象,InputStreamReader类实现输入字节流转为读取字符流,OutputStreamWriter类实现输出字节流转为写出字符流

 public static void main(String[] args) throws IOException {
        //InputStreamReader将字节输入流转为字符输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //OutputStreamWriter将字节输出流转为字符输出流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

这就是基本的IO流用法,希望有帮助。

;