Java基础学习 ---IO流

114 阅读11分钟

IO流

Java基础学习---点击进入学习

640 (2).jpg

IO流

1.File类

File类 文件类 提供了文件/文件夹操作的各种方法


import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 9:36
 *  File类 文件类 提供了文件/文件夹操作的各种方法
 */
public class TestFile {
    public static void main(String[] args) throws IOException {
        File file1 = new File("A.txt");

        if (!file1.exists()) {
            file1.createNewFile();
            System.out.println("是否可操作:" + file1.canExecute());
            System.out.println("是否可读:" + file1.canRead());
            System.out.println("是否可写:" + file1.canWrite());
            System.out.println("文件的相对路径" + file1.getPath());
            System.out.println("文件的绝对路径" + file1.getAbsolutePath());
            System.out.println("是否是一个文件:" + file1.isFile());
            System.out.println("是否是一个文件夹:" + file1.isDirectory());
            System.out.println("是否是一个隐藏文件:" + file1.isHidden());
            System.out.println("最后一次修改时间:" + new Date(file1.lastModified()));
            System.out.println("文件的名称:" + file1.getName());
            System.out.println("文件的大小,字节单位:" + file1.length());
            System.out.println("删除文件:" + file1.delete());
        }else{
            System.out.println("文件已存在");
        }
    }
}

2. 字节流读取文件InputStream

2.1 FileInputStream读取文件

InputStream

FileInputStream 字节读取流

read() 每次读取一个字节 返回值为读取的内容 如果读取到文件末尾 返回值为-1


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 10:10
 *  InputStream
 *  FileInputStream 字节读取流
 *
 *  read() 每次读取一个字节 返回值为读取的内容 如果读取到文件末尾 返回值为-1
 *
 */
public class TestFileInputStream1 {
    public static void main(String[] args)  {
        FileInputStream fileInputStream = null;
        try {
            System.out.println(10 / 0);

            fileInputStream = new FileInputStream("A.txt");

            System.out.println(10 / 0);

            int read = fileInputStream.read();

            System.out.println("read = " + read);

            read = fileInputStream.read();

            System.out.println("read = " + read);

            int readData = -1;

            while((readData = fileInputStream.read()) != -1){
                System.out.println((char)readData);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            // 关闭资源 关闭流
            try {
                // 非null判断是为了避免空指针异常
                if(fileInputStream != null){
                    fileInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

使用FileInputStream每次读取多个字节

read(byte [] data) 每次读取指定个数的字节 根据数组长度决定

返回值为实际读取字节的个数 读取到的内容保存在byte数组中 如果读取到文件末尾 返回值为-1

String(byte[] bytes, int offset, int length)

第一个参数为解析为字符串的byte数组 第二个参数为起始位置 第三个参数为解析字节个数


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 10:22
 *  使用FileInputStream每次读取多个字节
 *
 *  read(byte [] data) 每次读取指定个数的字节 根据数组长度决定
 * 返回值为实际读取字节的个数  读取到的内容保存在byte数组中 如果读取到文件末尾 返回值为-1
 *
 * String(byte[] bytes, int offset, int length)
 * 第一个参数为解析为字符串的byte数组 第二个参数为起始位置  第三个参数为解析字节个数
 *
 */
public class TestFileInputStream2 {
    public static void main(String[] args) {
        // 在try关键字之后书写小括号 将需要关闭的对象创建语句 书写在小括号内 可以实现自动关闭
        try(FileInputStream inputStream = new FileInputStream("C:\\Users\\WHD\\Desktop\\B.txt");) {

            byte [] data = new byte[5];

            int readCount = -1;

            while((readCount = inputStream.read(data)) != -1){
                System.out.println(readCount);
                System.out.println(new String(data, 0,readCount));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

一个中文占几个字节?

如果是GBK编码格式 一个中文占2个字节

如果是UTF-8编码格式 一个中文占3个字节

int available():可以从输入流中读取的字节数目 注意:不是文件大小 可读字节数会随着不断的读取减少

如果使用byte数组读取文件 而不确定文件有多少字节数的情况 可以使用available()方法来定义byte数组的长度

使用FileInputStream读取中文


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 10:33
 *  一个中文占几个字节?
 *  如果是GBK编码格式 一个中文占2个字节
 *  如果是UTF-8编码格式 一个中文占3个字节
 *
 *  int available():可以从输入流中读取的字节数目 注意:不是文件大小 可读字节数会随着不断的读取减少
 *
 *  如果使用byte数组读取文件 而不确定文件有多少字节数的情况 可以使用available()方法来定义byte数组的长度
 *
 *  使用FileInputStream读取中文
 */
public class TestFileInputStream3 {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("C:\\Users\\WHD\\Desktop\\B.txt");

        byte [] data = new byte[inputStream.available()];

        int readCount = -1;

        System.out.println(inputStream.available());

        while((readCount = inputStream.read(data)) != -1){
            System.out.println(new String(data,0,readCount));
        }




    }
}

3 .字节流写入OutputStream

3.1 FileOutputStream写入文件

OutputStream

FileOutputStream

如果文件不存在 则会自动创建文件

FileOutputStream(String name) 根据指定的文件路径和名称写入文件 默认为不追加

FileOutputStream(String name, boolean append) 根据指定的文件路径和名称写入文件 以及指定是否追加

write(int data) 每次写入一个字节


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 10:47
 *  OutputStream
 *  FileOutputStream
 *
 *  如果文件不存在 则会自动创建文件
 *  FileOutputStream(String name)  根据指定的文件路径和名称写入文件 默认为不追加
 *  FileOutputStream(String name, boolean append) 根据指定的文件路径和名称写入文件 以及指定是否追加
 *
 *  write(int data) 每次写入一个字节
 *
 *
 */
public class TestFileOutputStream1 {
    public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream("B.txt",true);

            fileOutputStream.write(20013);
            fileOutputStream.write(20320);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            // 关闭资源
            if(fileOutputStream != null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

使用FileOutputStream 写入中文

write(byte [] data) 每次写入一个byte数组


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 10:52
 *  使用FileOutputStream 写入中文
 *  write(byte [] data) 每次写入一个byte数组
 */
public class TestFileOutputStream2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("C.txt");

        byte [] data1 = {65,66,67,68,69,70};

        String str = "世界你好 哈哈哈哈";

        byte[] bytes = str.getBytes();

        fileOutputStream.write(data1);
        fileOutputStream.write(bytes);


        fileOutputStream.write("你好啊 hello world 666 世界你好".getBytes());

    }
}

4. 字符读取流Reader

4.1 InputStreamReader(桥接流/转换流)

Reader

InputStreamReader 桥接流 字符流 可以将一个字节流转换为字符流

int read() 每次读取一个字符 返回值为读取的内容 如果读取到文件末尾返回-1


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:15
 * Reader
 * InputStreamReader 桥接流 字符流  可以将一个字节流转换为字符流
 * <p>
 * int read() 每次读取一个字符 返回值为读取的内容 如果读取到文件末尾返回-1
 *
 */
public class TestInputStreamReader1 {

    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        InputStreamReader reader = null;
        try {
            fileInputStream =  new FileInputStream("C.txt");
            reader =  new InputStreamReader(fileInputStream);

            int readData = -1;
            while((readData = reader.read()) != -1){
                System.out.println((char)readData);
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            // 关闭资源  先用后关
            // ctrl + alt + T 选择结构包括选中的代码
            try {
                if(reader != null){
                    reader.close();
                }

                if(fileInputStream != null){
                    fileInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

int read(char [] data) 每次读取一个字符数组 返回值为读取字符的个数 读取到的内容保存在数组中

如果读取到文件末尾返回-1


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:22
 *  int read(char [] data) 每次读取一个字符数组 返回值为读取字符的个数 读取到的内容保存在数组中
 *  如果读取到文件末尾返回-1
 */
public class TestInputStreamReader2 {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("C.txt");

        InputStreamReader reader = new InputStreamReader(inputStream);

        char [] data = new char[5];

        int readCount = -1;

        while((readCount = reader.read(data)) != -1){
            System.out.println(readCount);
            System.out.println(new String(data,0,readCount));
        }

        // 关闭资源

    }
}

使用InputStreamReader来解决读取文件乱码问题


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

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:27
 *  使用InputStreamReader来解决读取文件乱码问题
 */
public class TestInputStreamReader3 {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("C:\\Users\\WHD\\Desktop\\B.txt");
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");

        char [] data = new char[5];

        int readCount = -1;

        while((readCount = inputStreamReader.read(data)) != -1){
            System.out.println(new String(data,0,readCount));
        }

        // 关闭资源



    }
}

4.2 BufferedReader(缓冲流)

Reader

BufferedReader 带有缓冲区的字符读取流 可以每次读取一行 readLine


import java.io.*;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:44
 *  Reader
 *  BufferedReader 带有缓冲区的字符读取流 可以每次读取一行  readLine
 */
public class TestBufferedReader1 {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("C.txt");
        BufferedReader reader = new BufferedReader(fileReader);

        String line = null;

        while((line = reader.readLine()) !=  null){
            System.out.println(line);
        }
        // 关闭资源
    }
}

4.3 FileReader(字符流)

Reader

InputStreamReader

FileReader 只能本地平台默认的编码格式读取文件

read() 读取一个字符

read(char [] data) 读取多个字符


import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:34
 *  Reader
 *  InputStreamReader
 *  FileReader 只能本地平台默认的编码格式读取文件
 *
 *  read() 读取一个字符
 *  read(char [] data) 读取多个字符
 */
public class TestFileReader1 {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("C.txt");

            int readData = -1;

            while((readData = reader.read()) != -1){
                System.out.println((char)readData);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            // 关闭资源
        }
    }
}

使用FileReader每次读取一个字符数组

read(char [] data) 读取多个字符


import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 14:37
 *  使用FileReader每次读取一个字符数组
 *  read(char [] data) 读取多个字符
 */
public class TestFileReader2 {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("C.txt");

        char [] data = new char[3];

        int readCount = -1;

        while((readCount = reader.read(data)) != -1){
            System.out.println(new String(data,0,readCount));
        }

        // 关闭资源
    }
}

5. 字符写入流Writer

5.1 OutputStreamWriter(桥接流/转换流)

Writer

OutputStreamWriter 字符流 桥接流/转换流 支持传入一个字节流写入对象 构建一个字符写入流对象

write(String str)


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:07
 *  Writer
 *  OutputStreamWriter 字符流 桥接流/转换流 支持传入一个字节流写入对象 构建一个字符写入流对象
 *  write(String str)
 */
public class TestOutputStreamWriter1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("D.txt",true);

        OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream);

        writer.write("世界你好 hello world 6666 12334343");

        // writer.flush(); // 字符流必须刷新才会将内容写入到文件中

        writer.close();

    }
}

OutputStreamWriter 指定写入文件的编码格式


import java.io.*;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:12
 *  OutputStreamWriter 指定写入文件的编码格式
 */
public class TestOutputStreamWriter2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("E.txt",true);

        OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream,"gbk");

        writer.write("世界你好 hello world 666");

        writer.flush();

        writer.close();



    }
}

5.2 FileWriter(字符流)

Writer

OutputStreamWriter

FileWriter 只能按照本地平台默认的编码格式写入文件 最基本的字符流


import java.io.FileWriter;
import java.io.IOException;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:17
 *  Writer
 *  OutputStreamWriter
 *  FileWriter 只能按照本地平台默认的编码格式写入文件 最基本的字符流
 */
public class TestFileWriter {
    public static void main(String[] args) throws IOException {
        FileWriter writer = new FileWriter("F.txt",true);

        writer.write("世界你好 hello world 666");

        writer.close();
    }
}

5.3 BufferedWriter(缓冲流)

BufferedWriter 带有缓冲区的字符写入流


import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:21
 *  BufferedWriter 带有缓冲区的字符写入流
 */
public class TestBufferedWriter1 {
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("G.txt");
        BufferedWriter writer = new BufferedWriter(fileWriter);

        writer.write("世界你好 \n hello \n  wo\n rld 666  1");
        writer.newLine();
        writer.write("世界你好 hello \n wo\n rl\n d 666  2");

        writer.close();
        fileWriter.close();
    }
}

6. 数据流DataStream

DataInputStream 数据读取流 字节流

read(byte [] data)

DataOutputStream 数据写入流 字节流

write(byte [] data)


import java.io.*;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:29
 *  DataInputStream 数据读取流 字节流
 *  read(byte [] data)
 *  DataOutputStream 数据写入流 字节流
 *  write(byte [] data)
 */
public class TestDataStream {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\beauty\\GOGO全球高清大胆美女花苑制服诱惑丝袜美腿丝袜亚洲综合\\1a160d77f4.jpg");

        DataInputStream dataInputStream = new DataInputStream(inputStream);

        byte [] data = new byte[inputStream.available()];

        dataInputStream.read(data);

        FileOutputStream fileOutputStream = new FileOutputStream("girl.jpg");

        DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);

        dataOutputStream.write(data);

    }
}

7.对象流

序列化:序列化是将对象的状态写入到特定的流中的过程

反序列化:反序列化则是从特定的流中获取数据重新构建对象的过程

被序列的类 必须实现Serializable接口 此接口为空接口 属于一个标记

JVM会通过安全检查的方式 检查被序列化的类是否实现了此接口 如果没有实现 则抛出异常

实现此接口的目的在于 JVM会自动生成序列化ID 以区分当前类的版本 等信息 用于区分当前类的唯一性

ObjectInputStream 对象读取流 readObject()

ObjectOutputStream 对象写入流 writeObject()

被transient修饰的属性不能被序列化


import java.io.*;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:40
 *  序列化:序列化是将对象的状态写入到特定的流中的过程
 *  反序列化:反序列化则是从特定的流中获取数据重新构建对象的过程
 *  被序列的类 必须实现Serializable接口 此接口为空接口 属于一个标记
 *
 *  JVM会通过安全检查的方式 检查被序列化的类是否实现了此接口 如果没有实现 则抛出异常
 *  实现此接口的目的在于 JVM会自动生成序列化ID 以区分当前类的版本 等信息  用于区分当前类的唯一性
 *
 *
 *  ObjectInputStream 对象读取流 readObject()
 *  ObjectOutputStream 对象写入流 writeObject()
 *
 *  被transient修饰的属性不能被序列化 
 *
 */
public class TestObjectStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student stu1 = new Student("赵四", 25,"深圳");
        Student stu2 = new Student("大拿", 30,"深圳");
        Student stu3 = new Student("小宝", 66,"深圳");

        FileOutputStream fileOutputStream = new FileOutputStream("stu.txt");

        ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);

        outputStream.writeObject(stu1);
        outputStream.writeObject(stu2);
        outputStream.writeObject(stu3);


        FileInputStream fileInputStream = new FileInputStream("stu.txt");

        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        while(fileInputStream.available() > 0){
            Object o = objectInputStream.readObject();
            System.out.println("o = " + o);
        }

    }
}

import java.io.Serializable;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/23 15:43
 */
public class Student implements Serializable {


    private String name;
    private int age;

    private transient String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    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;
    }

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

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