Java的IO流

前言

Java通过IO流获取文件中的数据,并把数据持久化。

Java的IO流体系很庞大,也很灵活;

一、File类

我们想要在Java中读写文件,首先得有1个文件;

1个File类的对象代表1个文件或者1个文件夹,我们通过File类的对象,完成对文件/目录的创建和修改操作;

package IOStream;

import java.io.File;

public class TestFile {
    public static void main(String[] args) {
        try {
            File file = new File("student/zhanggen.txt");


            //0.判断相关API
            //判断文件是否存在?
            System.out.println(file.exists());
            //判断文件是否为绝对路径?
            System.out.println(file.isAbsolute());
            //判断是否为目录?
            System.out.println(file.isDirectory());
            //判断是否为文件?
            System.out.println(file.isFile());

            //1.创建文件
            // f.createNewFile();

            //获取当前文件/目录的父级目录(对象)
            System.out.println(file.getParentFile());
            //获取当前文件/目录的名称(字符串)
            System.out.println(file.getParent());

            //2.创建文件夹
            //创建文件夹:只能创建1级目录
            file.mkdir();
            //创建文件夹:创建多级目录
            file.mkdirs();

            //3.文件/目录重用名
            file.renameTo(new File("newfile.txt"));

            //4.查看相关API
            //查看文件的大小
            System.out.println(file.length());
            //查看文件的名字
            System.out.println(file.getName());


            //5.文件/目录删除
            //file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

1.创建1个文件的完整过程

package IOStream;

import java.io.File;

public class TetsCreateFile {
    public static void main(String[] args) {

        File file = new File("java/file/test.txt");

        //1.判断父级目录是否存在?
        File ParentDirectory = new File(file.getParentFile().getAbsolutePath());
        if (!ParentDirectory.exists()) {
            ParentDirectory.mkdirs();
        }
        //2.判断文件是否存在?
        if (!file.exists()) {
            try {
                //3.文件不存在则创建文件!
                file.createNewFile();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }


    }
}

二、IO流简介

对于程序设计语言而言,输入输出系统(Input/Output)是非常核心的功能。

程序需要从配置文件/数据库中获取数据来内存中处理,也需要把在内存中处理好的数据保存到文件/数据库中。

1.什么是IO

以程序为中心,我们从外部数据源(文件、数据库)中读取外部数据到内存称之为Input;

以程序为中心,我们处理完内存中数据,持久化到硬盘或者数据称之为Output;                写

以上2个动作我们统称为IO,也就是Input和Output这2个单词的缩写。

2.输入出流流

IO流是输入流和输出流的统称;

输入流:程序通过输入流,把数据输入到内存,进行处理;  

输出流:程序通过输出流,把数据输出到硬盘,进行持久化;

3.IO流的种类

在java中我们通过IO流获取和保存数据

(1)根据IO流的方向,我们把IO流分为输入流和输出流;

(2)根据IO流中传输的数据,分为字节流和字符流;

(3)根据IO流的功能,分为字节流和处理流;

其中节点流就是直接连接到文件的IO流;

处理流是嵌套在其他IO流上,不直接连接文件;

传输字节流:InputStream/OutputStream

传输字符流:Reader/Writer

在Java中以上4类,是所有IO类的抽象父类;我们通过它们的子类完成文件内容的读和写;

三、节点流

使用字符流读(FileReaderFileWriter)取文件中的文字信息,

使用字节流(FileInputStreamFileOutputStream)读取非文本信息,例如图片、声音、视频、图片等二进制信息。

1.FileInputStream读文件

package IOStream;

import java.io.File;
import java.io.FileInputStream;

public class TestFileInputStream01 {
    public static void main(String[] args) throws Exception {
        //1.逐一读取文件
        FileInputStream fis = new FileInputStream("student/zhanggen.txt");
        // 读取1个字节(8个位)的数据,正好是1个英文字母,
        // 想要阅读1个汉字就需要1次阅读4个字节
        System.out.println((char) fis.read());
        System.out.println((char) fis.read());
        System.out.println((char) fis.read());
        fis.close();

        //2.设置字节数组作为缓存,读取文件;
        FileInputStream fis01 = new FileInputStream("student/zhanggen.txt");
        byte[] byteArray = new byte[1024];
        fis01.read(byteArray);
        //1个Char内存上存储的是Uicode 编码的数字, 1个字符串是由多个字符组成的Char[]
        //所以字节数组可以转成1个字符串;
        System.out.println(new String(byteArray));
        fis01.close();

        //3.循环读取+缓存
        FileInputStream fis02 = new FileInputStream("student/zhanggen.txt");
        byte[] bytesBuffer = new byte[1024];
        int len = 0;
        while ((len = fis02.read(bytesBuffer)) != -1) {
            System.out.println(new String(bytesBuffer, 0, len));
        }
        fis02.close();
    }
}

2.FileOutputStream写文件

package IOStream;

import java.io.FileOutputStream;

public class TestFileOutputStream02 {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("student/zhanggen.txt");
        //把字符串变成字节数组getBytes()
        fos.write("渣女最常用的手段:情绪“控制”,男人不要再被骗;".getBytes());
        fos.flush();
        fos.close();

    }
}

3.FileReader读文件

package IOStream;

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

public class TestFileReader03 {
    public static void main(String[] args) throws Exception {
        FileReader file01 = new FileReader("student/zhanggen.txt");
        //1.以1个字符为单位进行读取
        System.out.println((char) file01.read());
        file01.close();
        //2.一次性读取文件内容
        FileReader file02 = new FileReader("student/zhanggen.txt");
        //把文件内容全部放到1个字节数组中了
        char[] charArray = new char[1024];
        int count = file02.read(charArray);
        System.out.println(new String(charArray, 0, count));
        file02.close();

        //3.循环读取
        FileReader file03 = new FileReader("student/zhanggen.txt");
        int count01 = 0;
        char[] charArray01 = new char[1024];
        //把文件内容全部放到1个字节数组中了
        while ((count01 = file03.read(charArray01)) != -1) {
            System.out.println(new String(charArray01, 0, count01));
        }
        file03.close();

    }
}

4.FileWriter写文件

package IOStream;

import java.io.FileWriter;

public class TestFileWriter04 {
    public static void main(String[] args) throws Exception {
        //append=ture开启追加写模式
        FileWriter file01 = new FileWriter("student/zhanggen.txt", true);
        file01.write("您好时间简史\r\n");
        file01.flush();
        file01.close();
    }
}

5.copy和move文件

package IOStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class TestCopy {

    public static void main(String[] args) throws Exception {
        copy("student/胡一菲.jpg", "student/胡二飞.jpg");

    }

    public static void copy(String soure, String des) throws Exception {
        FileInputStream fis = new FileInputStream(soure);
        FileOutputStream fos = new FileOutputStream(des);
        byte[] buffer = new byte[1024];
        while ((fis.read(buffer)) != -1) {
            fos.write(buffer);
        }
        fos.flush();
        fos.close();
        fis.close();

    }

    public static void move(String soure, String des) throws Exception {
        copy("student/ef.jpg", "student/new_ef.jpg");
        File file = new File(soure);
        if (file.exists()) {
            file.delete();
        }

    }
}

四、处理流

处理流就是对节点流进行过滤和处理;

1.缓冲流

带有缓冲区的流就是缓冲流,BufferedReader可以像Python中的readLine()一样,一行一行地读取数据;

package IOStream.Buffer;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;

public class Test01 {
    public static void main(String[] args) throws Exception {
        //处理流嵌套在节点流上;
//        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("student/zhanggen.txt"));
        //一行一行地读取内容
        BufferedReader br = new BufferedReader(new FileReader("student/zhanggen.txt"));
        String line = "";
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}

2.转换流

电在传输的过程中传输的是高压电,高压电必须经过变电所进行降压(把高压电降低到220V)才能供居民使用;

转换流就是充当着变电所的功能;

Scanner sc=new Scanner(System.in);

我们可以使用InputStreamReader、OutputStreamWriter把字节流转换成字符流,但是不能把字符流转换成字节流;

InputStreamReader

package IOStream.convert;

import java.io.*;

public class Test01 {
    public static void main(String[] args) throws Exception {
        //把字节输入流 (System.out)转换成字符输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.close(); //关闭了
        System.out.println("111");


    }
}

OutputStreamWriter

package IOStream.convert;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class Tetst02 {
    public static void main(String[] args) throws Exception {
        //把字节输出流(System.out)转换成字符输出流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write("您好,我是周润发!");
        bw.flush();
//        bw.close(); //注意:关闭了System.out,我们就无法打印了
        System.out.println("久仰!");
    }
}

3.对象流

对象流可以把对象这种结构化的数据保存到文件中,还能从文件中加载对象到程序中使用;

package IOStream.Obj;

import java.io.*;

//Java中的类实现了Serializable接口,它的对象才能被序列化。
class Person implements Serializable {
    private int id;
    private String name;
    private int age;

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 class TestObj {
    public static void main(String[] args) throws Exception {
        String fileName = "student/person.dat";

        //序列化:把对象转换成字节
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
        Person p1 = new Person(1, "刘老根", 18);
        oos.writeObject(p1);
        oos.flush();
        oos.close();

        //反序列化:把字节转回对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
        Object obj = ois.readObject();
        Person p2 = (Person) obj;
        System.out.println(p1.getId());
        System.out.println(p2.getName());
        System.out.println(p2.getAge());
        ois.close();


    }
}

五、练习

偷梁换柱,模拟Word文件的内容修改功能,把文件中内容李白替换成李太白;

package FileOption;

        import java.io.*;

public class Word {
    public static void main(String[] args) throws Exception {
        replace("student/zhanggen.txt", "未来", "Future");
    }

    public static void replace(String fileName, String oldString, String newString) throws Exception {

        File sourceFile = new File(fileName);
        String sourceFileName = sourceFile.getName();
        String temFileName = String.format("%s/副本_%s", sourceFile.getParentFile().getAbsolutePath(), sourceFileName);
        File temFile = new File(temFileName);
        if (!temFile.exists()) {
            temFile.createNewFile();
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile.getAbsoluteFile())));
        BufferedWriter bw = new BufferedWriter(new FileWriter(temFile));
        String line = "";
        while ((line = br.readLine()) != null) {
            line = line.replace(oldString, newString);
            bw.write(line);
            bw.newLine();//另起一行
            bw.flush();
        }
        br.close();
        bw.close();
        sourceFile.delete(); //先删除源文件
        temFile.renameTo(sourceFile);//再使用临时文件替换源文件,偷梁换柱!


    }
}

参考

原文地址:https://www.cnblogs.com/sss4/p/15583778.html