Java这些IO流你了解嘛

字节流

FileInputStream

FileInputSteam:用于读取诸如图像数据的原始字节流

FileInputStream常用方法:

  • FileInputStream(File file)//创建文件输入流
  • read()//从该输入流读取一个字节的数据
  • read(byte[] b)//从该输入流读取最多 b.length个字节的数据为字节数组。
  • read(byte[] b, int off, int len) //从该输入流读取最多 len字节的数据为字节数组。

读文件

mport java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInput {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //utf-8进行存储,一个英文字母占一个字节,一个中文占3个字节
        //如果文本文件,那么就不要使用字节流读取了,建议使用字符流
        //read()读取一个字节,返回int类型,都是正数
        //方式一:
        Input01();
        //方式二
        Input02();

    }
    public static void Input01() throws IOException {
    
    
        //利用字节流读取文件
        File file = new File("E:\\test.txt");
        FileInputStream fi = new FileInputStream(file);

        int read = fi.read();
        while(read!=-1){
    
    
            System.out.print((char)read);
            read=fi.read();
        }

        fi.close();
    }
    public static void Input02() throws IOException {
    
    
        FileInputStream fi=new FileInputStream(new File("E:\\test.txt"));
        byte[] b=new byte[8];
        int len=fi.read(b);
        while(len!=-1){
    
    
            for(int i=0;i<len;i++){
    
    
                System.out.print((char) b[i]);
            }
            len=fi.read(b);
        }
        fi.close();
    }
}

FileOutputStream

FileOutputStream用于写入诸如图像数据的原始字节流。

FileOutputStream常用方法:

  • FileOutputStream(File file)//创建文件输出流以写入由指定的 File对象表示的文件。
  • FileOutputStream(File file,boolean append)//创建文件输出流以覆盖(false)或者追加(true)的方式写入。
  • write(int b)//将指定的字节写入此文件。
  • write(byte[] b)//将b.lenth个字节从指定数组写入此文件中。

写文件

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileOutput {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileOutputStream fo=new FileOutputStream(new File("E:\\demo.txt"));
        String str="hello java!";//写入的内容
        byte[] b = str.getBytes(StandardCharsets.UTF_8);//按utf-8编码格式转成字节数组
        fo.write(b);//写入操作
        fo.close();//关闭流
    }
}

文件拷贝

import java.io.*;

public class FileCopy {
    
    
    public static void main(String[] args) throws IOException {
    
    
        File f1 = new File("E:\\test.txt");
        File f2 = new File("E:\\demo.txt");
        FileInputStream fi = new FileInputStream(f1);
        FileOutputStream fo = new FileOutputStream(f2);
        byte[] b = new byte[8];
        int len = fi.read(b);
        while (len != -1) {
    
    
            fo.write(b, 0, len);
            len = fi.read(b);
        }
        fo.close();
        fi.close();
    }
}

字符流

在这里插入图片描述

FileReader

FileReader:是用于读取字符流。

FileReader常用方法:

  • new FileReader(File file);//构造方法
  • read();//每次读取单个字符,返回该字符,如果读到文件末尾返回-1
  • read(char[] ch);//读取多个到数组,返回读取到的字符数,如果到文件末尾返回-1

读文件

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

public class FileRead {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //方式一
        Read01();
        //方式二
        Read02();

    }

    public static void Read01() throws IOException {
    
    
        String path = "E:\\Test\\test01.txt";
        File file = new File(path);
        FileReader fileReader = new FileReader(file);
        int read = fileReader.read();
        while (read != -1) {
    
    
            System.out.print((char) read);
            read = fileReader.read();
        }
        fileReader.close();
    }

    public static void Read02() throws IOException {
    
    
        File file = new File("E:\\Test\\test01.txt");
        FileReader fileReader = new FileReader(file);
        char[] ch = new char[8];
        int len = fileReader.read(ch);//缓冲数组
        while (len != -1) {
    
    
//            for (int i=0;i<len;i++){
    
    
//                System.out.print(ch[i]);
//            }
//            len=fileReader.read(ch);
            //将数组转为string
            String str = new String(ch, 0, len);
            System.out.print(str);
            len = fileReader.read(ch);
        }
        fileReader.close();
    }
}

FileWriter

FileWriter:是用于写入字符流。

FileWriter常用方法:

  • new FileWriter(File file,boolean true);//构造方法,如果目标文件不存在,就自动创建该文件,默认为false,对源文件进行覆盖操作,true,对源文件末尾进行追加。
  • write();//写入单个字符
  • write(char[] ch);//写入指定数组内容,也可写入数组的指定部分
  • write(String str);//写入指定字符串,也可写入字符串的指定部分

注意:FileWriter使用后,必须要关闭(close)或者刷新(flush),否者写入不到指定文件!
写文件

import java.io.*;

public class FileWrite {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //一个一个字符写入
        // new FileWriter(file,false)对源文件按进行覆盖操作
        // new FileWriter(file,true)对源文件进行追加,而不是覆盖
        Write01();
        //利用缓冲数组输出
        Write02();

    }

    public static void Write01() throws IOException {
    
    
        //如果目标文件不存在的话,那么会自动创建此文件
        File file = new File("E:\\test.txt");
        FileWriter fileWrite = new FileWriter(file, true);

        String str = "hello java!!!";
        for (int i = 0; i < str.length(); i++) {
    
    
            fileWrite.write(str.charAt(i));
        }
        fileWrite.close();
    }

    public static void Write02() throws IOException {
    
    
        File file = new File("E:\\test.txt");
        FileWriter fileWriter = new FileWriter(file, true);
        String str = "你好,java!";
        char[] chars = str.toCharArray();
        fileWriter.write(chars);
        fileWriter.close();
    }
}

文件拷贝

import java.io.*;

//注意:不要用字符流去操作非文本文件
/*
* 文本文件:.txt/.java/.c/.cpp-->建议使用字符操作
* 非文本文件:.jpj/.mp3/.mp4/.doc/.ppt-->建议使用字节流操作
* */

public class FileCopy {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //有一个源文件和一个目标文件
        File f1 = new File("E:\\test.txt");
        File f2 = new File("E:\\demo.txt");
        //输入输出
        FileReader fileReader = new FileReader(f1);
        FileWriter fileWriter = new FileWriter(f2);

        //一个一个字符复制
//        int read=fileReader.read();
//        while (read!=-1){
    
    
//            fileWriter.write(read);
//            read=fileReader.read();
//        }

        //利用字符数组
        char[] ch=new char[1024];
        int len=fileReader.read(ch);
        while(len!=-1){
    
    
            String str=new String(ch,0,len);
            fileWriter.write(str);
            //fileWriter.write(ch,0,len);
            len=fileReader.read(ch);
        }

        //关闭流
        fileWriter.close();
        fileReader.close();
    }
}

缓冲(处理)流

一般情况下,我们使用字节字符流时,每次都是从源文件中读取/写入数据,这种操作效率比较低。
在这里插入图片描述
而利用缓冲(处理流),在程序(内存)里开辟一个缓冲区,然后在缓冲区里进行数据的读写,这样就不用每次都到源文件中操作。

在这里插入图片描述

缓冲流的使用

  • 创建文件对象(new File())
  • 创建输入输出流对象(new FileInputStream()/new FileReader())
  • 创建缓冲流对象(new BufferedInputStream(fi)/new BufferedReader(fr))
  • 利用缓冲流操作读写(read()/write())
  • 关闭流(bf.close())

如果处理流包裹着节点流的话,那么其实只要关闭高级流(处理流),那么里面的字节流也会随之被关闭。

缓冲字节流

当创建BufferedInputStream时,将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次有多个字节。
BufferedOutputStream实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。

常用方法:

  • new BufferedInputStream(InputStream in)//创建一个 BufferedInputStream并保存其参数,输入流 in
  • new BufferedInputStream(InputStream in,int size)//创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in
  • read()//与InputStream中read()用法相同
  • read(byte[] b,int off,int len)// 与InputStream中read(byte[] b,int off,int len)相同
  • BufferedOutputStream(OutputStream out) //创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size) //创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流
  • write(byte[] b, int off, int len) //从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。
  • write(int b)//将指定的字节写入缓冲的输出流。

利用缓冲字节流对文件的拷贝

import java.io.*;

public class BufferedStream {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileInputStream fi = new FileInputStream(new File("E:\\test.txt"));
        FileOutputStream fo = new FileOutputStream(new File("E:\\demo.txr"));
        BufferedInputStream bis=new BufferedInputStream(fi);
        BufferedOutputStream bos=new BufferedOutputStream(fo);
        byte[] b=new byte[1024];
        int len=bis.read(b);
        while(len!=-1){
    
    
            bos.write(b,0,len);
            len=bis.read(b);
        }
        bos.close();
        bis.close();
    }
}

缓冲字符流

在使用字符缓冲流读文件时,使用readLine()可以读一行文字,返回的是一个字符串,如果我们要对这读取到这一行进行写操作时,就要手动的在下面添加换行,newLine(),不然的话会把所有的内容都写在同一行

利用缓冲字符流对文件的拷贝

import java.io.*;

public class BufferedRW {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileReader fr=new FileReader(new File("E:\\test.txt"));
        FileWriter fw=new FileWriter(new File("E:\\demo.txt"));
        BufferedReader bfr=new BufferedReader(fr);
        BufferedWriter bfw=new BufferedWriter(fw);
        String str=bfr.readLine();
        while(str!=null){
    
    
            bfw.write(str);
            bfw.newLine();
            str=bfr.readLine();
        }
        bfw.close();
        bfr.close();
    }
}

打印流

System.out:标准的输出流,默认情况下输出到控制台,返回的是打印流(PrintStream)

import java.io.PrintStream;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        PrintStream out = System.out;
        out.print("hello");//直接在控制台上写出,不换行
        out.println("java");//直接在控制台上写出,并且换行操作
        System.out.println("hello world");
    }
}

System.in:标准输入流,默认情况下,从键盘输入
Scanner:起扫描作用,扫描从键盘上输入的数据,还可以扫描其他流的数据

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class input {
    
    
    public static void main(String[] args) throws IOException {
    
    
        InputStream in = System.in;//得到标准的输入流
        int a=in.read();
        System.out.println(a);
        //Scanner可以扫描其他流的数据
        Scanner sc=new Scanner(System.in);
        int b=sc.nextInt();
        System.out.println(b);
        //Scanner扫描文件
        Scanner input=new Scanner(new FileInputStream(new File("E:\\test.txt")));
        while(input.hasNext()){
    
    
            System.out.println(input.next());
        }
    }
}

转换流

转换流的作用

将字节流和字符流进行转换

转换流属于字节流还是字符流?

属于字符流
InputStreamReader:字节输入流–>字符输入流
OutputStreamWriter:字符输出流–>字节输出流

在这里插入图片描述
使用转换流对文件的复制

import java.io.*;

public class Test02 {
    
    
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
    
    
        //1.有一个源文件
        File f1 = new File("d:\\Test.txt");
        //2.有一个目标文件:
        File f2 = new File("d:\\Demo.txt");
        //3.输入方向:
        FileInputStream fis = new FileInputStream(f1);
        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        //4.输出方向:
        FileOutputStream fos = new FileOutputStream(f2);
        OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
        //5.开始动作:
        char[] ch = new char[20];
        int len = isr.read(ch);
        while(len!=-1){
    
    
            osw.write(ch,0,len);
            len = isr.read(ch);
        }
        //6.关闭流:
        osw.close();
        isr.close();
    }
}

数据流

数据流:就是用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串写入内存变量中
DataOutputStream:将内存中的基本数据类型和字符串的变量写出文件中

利用DataOutputStream向外写出变量

public class Test01 {
    
    
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
    
    
        //DataOutputStream:  将内存中的基本数据类型和字符串的变量 写出  文件中
        File f = new File("d:\\Demo2.txt");
        FileOutputStream fos = new FileOutputStream(f);
        DataOutputStream dos = new DataOutputStream(fos);
        //向外将变量写到文件中去:
        dos.writeUTF("你好");
        dos.writeBoolean(false);
        dos.writeDouble(6.9);
        dos.writeInt(82);
        //关闭流:
        dos.close();
    }
}

打开文件可以看到,内容我们看不懂,这是给程序看的
在这里插入图片描述
我们用程序读取

import java.io.*;

public class Test02 {
    
    
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
    
    
        //DataInputStream:将文件中存储的基本数据类型和字符串  写入  内存的变量中
        DataInputStream dis = new DataInputStream(new FileInputStream(new File("d:\\Demo2.txt")));
        //将文件中内容读取到程序中来:
        System.out.println(dis.readUTF());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readDouble());
        System.out.println(dis.readInt());
        //关闭流:
        dis.close();
    }
}

输出
在这里插入图片描述
要求:写出的类型跟读入的类型 必须 要匹配!

对象流

数据流:就是用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串写入内存变量中
DataOutputStream:将内存中的基本数据类型和字符串的变量写出文件中

序列化和反序列化

  • 序列化就是在保存数据时,保存数据的值和数据类型

  • 反序列化就是在恢复数据时,恢复数据的值和数据类型

需要让某个对象支持序列化和反序列化机制,则必须让其类是可序列化的,为了让某个类可序列化的,该类必须实现两个接口之一:

  • Serializable:标记接口,接口内部,什么都没有,这种接口叫 标识接口。起到标识作用,标识什么呢?只要实现这个接口的类的对象才能序列化,否则不可以。
  • Externalizable:一般不使用

serialVersionUID:凡是实现Serializable接口(标识接口)的类都有一个表示序列化版本标识符的静态常量

  • private static final long serialVersionUID
  • serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序加化时是否兼容
  • 如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
  • 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

IDEA配置序列化版本号
在这里插入图片描述
alt+enter
在这里插入图片描述

序列化细节:

  • 被序列化的类的内部的所有属性,必须是可序列化的 (基本数据类型都是可序列化的)
  • static,transient修饰的属性 不可以被序列化。
public class Person implements Serializable {
    
    
    private static final long serialVersionUID = 8027651838638826533L;
    private transient String name;
    private static 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 Person() {
    
    
    }
    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试方法

public class Test01 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //序列化:将内存中对象 ---》 文件:
        //有一个对象:
        Person p = new Person("张三",19);
        //有对象流:
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\Demo4.txt")));
        //向外写:
        oos.writeObject(p);
        //关闭流:
        oos.close();
    }
}
public class Test02 {
    
    
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    
    
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\Demo4.txt")));
        //读入内存:
        Person p = (Person)(ois.readObject());
        System.out.println(p);
        //关闭流:
        ois.close();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_47383392/article/details/124406736
今日推荐