欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA IO流小结

程序员文章站 2022-04-03 18:34:58
...

之前一直对JavaIO不太熟悉,在这里做个小结

Java是以流的方式抽象表示不同的输入、输出源。按流的流向分,可以分为输入流和输出流;按操作的数据单元分,可以分为字节流和字符流。

Java的IO流主要有以下四种抽象基类,无法直接创建实例
JAVA IO流小结
向文件中写入数据:
写入数据的原理(内存–>硬盘):
Java程序–>JVM–>OS–>OS调用写数据的方法–>把数据写入到文件中

向文件中写入数据一般常用FileOutputStream和FileWriter
FileOutputStream:文件字节输出流,继承了InputStream
使用步骤:
1、创建一个FileOutputStream对象,构造方法中传入写入数据的目的地
2、调用FileOutputStream对象中的方法write,将数据写入到文件中
3、释放资源

FileOutputStream的构造方法
JAVA IO流小结

write方法的用法如下:
JAVA IO流小结

//使用字节输出流
 public static void main(String[] args) throws IOException {
       FileOutputStream fos=new FileOutputStream("E:\\java_repository\\123.txt");
       String a="你好";
        fos.write(a.getBytes());
        fos.close();
    }

FileWriter:文件字符输出流,继承了Writer
使用步骤:
1、创建FileWriter对象,构造方法中绑定要写入数据的目的地
2、使用FileWriter中的方法write,将数据写入到内存缓冲区中(把字节转换成字符)
3、使用FileWriter中的方法flush,把内存缓冲区的数据刷新到文件中
4、释放资源

write方法:
JAVA IO流小结

    public static void main(String[] args) throws IOException 
    {
        FileWriter fileWriter=new FileWriter("E:\\java_repository\\a.txt");
        fileWriter.write("你好");
        fileWriter.flush();
        fileWriter.close();
    }

flush和close的区别:
flush:刷新缓冲区,流对象可以继续使用
close:刷新缓冲区,再通知系统释放资源,流对象不能再使用了

从文件中读取数据
读取数据的原理(硬盘–>内存):
Java程序–>JVM–>OS–>OS读取数据的方法–>读取文件

从文件中读取数据一般常用FileInputStream和FileReader

FileInputStream:文件字节输入流,继承InputStream
使用步骤:
1、创建FileInputStream对象,构造方法中绑定要读取数据的目的地
2、使用FileWriter中的方法read,读取文件
3、释放资源

构造方法:
JAVA IO流小结
read方法:读取到文件的末尾返回-1
JAVA IO流小结

    //一次读一个字节
    private static void input1() throws IOException {
        FileInputStream fileInputStream=new FileInputStream("E:\\java_repository\\a.txt");
        int len=0;//记录读取到的字节
        while((len=fileInputStream.read())!=-1)
            System.out.println(len);
        fileInputStream.close();
    }
    //一次读多个字节
    private static void input2() throws IOException {
        FileInputStream fileInputStream=new FileInputStream("E:\\java_repository\\a.txt");
        byte[] b=new byte[100];
        int len=fileInputStream.read(b);//从输入流读取一定量的字节,储存在缓存区数组b中
        System.out.println(new String(b));
        fileInputStream.close();
    }

得到了文件中的字节数据,是以二进制码的形式表示的

FileReader:文件字符输入流,继承InputStreamReader和Reader
使用步骤:
1、创建FileReader对象,构造方法中绑定要读取数据的目的地
2、使用FileReader中的方法read,读取文件
3、释放资源
JAVA IO流小结

    public static void main(String[] args) throws IOException {
        FileReader fileReader=new FileReader("E:\\java_repository\\c.txt");
        char[] c=new char[100];
        fileReader.read(c);
        System.out.println(new String(c));
        fileReader.close();
    }

普通IO流的效率
由于普通IO流需要反复对硬盘进行读取、写入,每次只操作一个字节,效率是比较低的

    public static void main(String[] args) throws IOException {
        long start=System.currentTimeMillis();
        FileOutputStream fos=new FileOutputStream("E:\\java_repository\\2.jpg");
        FileInputStream fis=new FileInputStream("E:\\java_repository\\1.jpg");
        int len=0;
        while((len=fis.read())!=-1)
        {
            fos.write(len);
        }
        fos.close();
        fis.close();
        long end=System.currentTimeMillis();
        System.out.println("普通流复制时间:"+(end-start)+"ms");
    }

复制一个800多K的图片需要花费12s
JAVA IO流小结
JAVA IO流小结
如果使用数组作为缓存区,一次存储多个字节、可以大大提高效率

 private static void copy2() throws IOException {
        long start=System.currentTimeMillis();
        FileOutputStream fos=new FileOutputStream("E:\\java_repository\\2.jpg");
        FileInputStream fis=new FileInputStream("E:\\java_repository\\1.jpg");
        int len=0;
        byte[] b=new byte[1024];
        while((len=fis.read(b))!=-1)
        {
            fos.write(b,0,len);
        }
        fos.close();
        fis.close();
        long end=System.currentTimeMillis();
        System.out.println("普通流复制时间:"+(end-start)+"ms");
    }

JAVA IO流小结
缓冲流
Java还提供了缓冲流来减少系统IO次数,提高读写的效率
字节缓冲流:BufferedInputStream 、BufferedOutputStream
字符缓冲流:BufferedReader、BufferedWriter

原理:给基本的字节输入、输出流增加一个内置的缓冲区(数组),提高读写效率

字节缓冲输出流:

    public static void output1() throws IOException {
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\c.txt"));
        String a="你好";
        bufferedOutputStream.write(a.getBytes());
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
    }

字节缓冲输入流:

    public static void input01() throws IOException {
        BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\c.txt"));
        int len=0;
        while((len=bufferedInputStream.read())!=-1)
            System.out.println(len);
        bufferedInputStream.close();
    }
    public static void input02() throws IOException {
        BufferedReader bufferedReader=new BufferedReader(new FileReader("E:\\java_repository\\123.txt"));
        char[] c=new char[100];
        bufferedReader.read(c);
        System.out.println(c);
        bufferedReader.close();
    }

现在再使用缓冲流对文件进行复制操作,可以发现读写效率得到很大提升

//一次读取一个字节
 private static void copy4() throws IOException {
        long start=System.currentTimeMillis();
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\2.jpg"));
        BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\1.jpg"));
        int len=0;
        while((len=bufferedInputStream.read())!=-1)
        {
            bufferedOutputStream.write(len);
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();
        long end=System.currentTimeMillis();
        System.out.println("缓冲流复制时间:"+(end-start)+"ms");
    }

JAVA IO流小结

  //一次读取多个字节
    private static void copy3() throws IOException {
        long start=System.currentTimeMillis();
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\2.jpg"));
        BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\1.jpg"));
        int len=0;
        byte[] b=new byte[1024];
        while((len=bufferedInputStream.read(b))!=-1)
        {
            bufferedOutputStream.write(b,0,len);
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();
        long end=System.currentTimeMillis();
        System.out.println("缓冲流复制时间:"+(end-start)+"ms");
    }

JAVA IO流小结

对象的序列化
对象的序列化就是把对象以流的形式,写入到文件中保存
对象的序列化流:ObjectOutputStream

对象的反序列化
把文件中保存的对象,以流的形式读取出来
对象的反序列化流:ObjectIntputStream

一个对象要想实现序列化的条件:
1、该类必须实现Serializable接口
2、该类的所有属性必须是可序列化的,如果一个属性不需要可序列化,该对象必须注明是瞬态的,使用transient关键字

示例:

package io;

import java.io.*;

public class IoObjectStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
       output();
       input();
    }

    private static void input() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("E:\\java_repository\\e.txt"));
        Object o=objectInputStream.readObject();
        objectInputStream.close();
        System.out.println(o);
    }

    private static void output() throws IOException {
        FileOutputStream fileOutputStream=new FileOutputStream("E:\\java_repository\\e.txt");
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(new Person("张三",23));
        objectOutputStream.close();
    }
}

问题:
每次修改类,都会给该类生成新的***,导致InvalidClassException
解决方法:
手动给该类增加***

static final long serialVersionUID=42L;