java IO

I/O流

  • 什么事文件

文件就是保存数据的地方

  • 文件流

文件在程序中是以流的方式来操作的

image-20231208222408963

流: 数据在数据源(文件) 和 程序(内存之间)经历的路径

输入流 : 数据从数据源(文件) 到程序(内存)的路径

输出流 : 数据从程序(内存) 到数据源文件的路径

1. 常用创建文件的操作

  • 创建文件对象相关的构造器的方法
new File(String pathName) // 根据路径构建一个 file 对象
new File(File parent, String child) // 根据 父目录文件 + 子路径构建
new File(String Parent, String Child) // 根据 父目录 + 子路径构建

image-20231208223403987

image-20231208223431559

package com.wxledu.file_;

import org.junit.Test;

import java.io.File;

/**
 * @author XXX
 * @version 1.0
 */
public class Directory_ {
    public static void main(String[] args) {

    }

    @Test
    public void m1(){
        String filePath = "d:\\news02";
        File file = new File(filePath);

        if (file.exists()){
            if (file.delete()){
                System.out.println(filePath + "删除成功");
            } else {
                System.out.println(filePath + "删除失败");
            }
        } else {
            System.out.println("该文件不存在");
        }
    }


    // 判断 D:\\demo02 是否存在,存在就删除,否则就提示不存在
    // 我们这里需要体会到,在java 编程中,目录也可以当做文件
    @Test
    public void m2(){
        String filePath = "D:\\demo02";
        File file = new File(filePath);
        if (file.exists()){
            if (file.delete()){
                System.out.println(filePath + "删除成功");
            } else {
                System.out.println(filePath + "删除失败");
            }
        } else {
            System.out.println(filePath + "目录不存在");
        }
    }


    // 判断 D:\\demo\\a\\b\\c 目录是否存在,如果存在就提示存在,不存在就创建
    // 创建一级目录 mkdir()  创建多级目录 mkdirs()
    @Test
    public void m3(){
        String directoryPath = "D:\\demo\\a\\b\\c";
        File file = new File(directoryPath);
        if (file.exists()){
            System.out.println(directoryPath + "目录存在");
        } else {
            if (file.mkdirs()){
                System.out.println(directoryPath + " 该目录创建成功");
            } else {
                System.out.println(directoryPath + "创建失败");
            }
        }
    }
}

image-20231230154703172

2. InputeStream 字节输入流

InputStream 常用子类

  1. FileInputeStream 文件输入流
  2. BufferedInputStream 缓冲字节输入流
  3. ObjectInputStream 对象字节输入流
package com.wxledu.outputStream_;

import org.junit.Test;

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

/**
 * @author xxx
 * @version 1.0
 */
public class OutputStream01 {
    public static void main(String[] args) {

    }

    /**
     * 演示使用 FileOutputStream 写入文件中
     * 如果文件不存在,就创建文件
     */
    @Test
    public void writeFile(){

        String filePath = "D:\\a.txt";
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;

        try {
            // 得到 fileOutPutStream 对象

            // 1. new FileOutputStream(filePath) 创建方式,写入的内容是,会覆盖原来的内容
            // 2. new FileOutPutStream(filePath, true) 创建方式,写入的内容是,追加到文件的后面
            fileOutputStream = new FileOutputStream(filePath, true);
            // char - > int
            // 写入一个字节
            // fileOutputStream.write('H');

            // 写入一个字符串
            // str.getBytes() 可以把字符串 - > 字节数组
            String str = "hello,world!";
            // fileOutputStream.write(str.getBytes());

            /*
            write(byte[] b, int off, int len)
            将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。
             */

            fileOutputStream.write(str.getBytes(), 0, str.length());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

3. I/O 流体系图-常用类

FileReader FileWriter 介绍

FileReader

  1. new FileReader(file/String)
  2. read: 每次读取单个字符,返回该字符,如果到文件末尾返回 -1
  3. read(char[]) : 批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回 -1

相关 API

1)new String(char[]) 将 char[] 转换成 String

2)new String(char[], off, len): 将 char[] 的指定部分转换成 String

FileWriter

  1. new FileWriter(File / String) : 覆盖模式, 相当于流的指针在首端
  2. new FileWriter(File / String, true) 追加模式,相当于流的指针在行尾
  3. write(int) : 写入单个字符
  4. write(char[]) 写入指定数组
  5. write(char[], off, len) : 写入数组的指定部分
  6. write(String) 写入整个字符串
  7. write(string, off, len) 写入字符串的指定部分

相关 API

String 类 toCharArray : 将 String 转换成 char[]

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

4. 节点流和处理流

节点流:节点流可以从一个特定的数据源读写数据,如 FileReader FileWriter

数据源就是存放数据的地方

image-20240106222729816

处理流(也叫包装流) 是 “连接” 在已存在的流(节点流或处理流) 之上, 为程序提供更为强大的读写功能, 如 BufferedReader BufferedWriter 对节点流进行包装让我们这个流更强大

image-20240110195007268

BufferedReader 类中有属性 Reader , 即可以封装一个节点流 该节点流可以是任意的

image-20240110195117247

image-20240110195408006

image-20240110195718055

4.1 节点流和处理流的区别于联系

  • 节点流是 底层流 / 低级流, 直接跟数据源相连
  • 处理流包装节点流,既可以消除不同节点流之间的额差异,也可以提供更方便的方法来完成输入输出[源码理解]
  • 处理流(也叫包装流)对节点流进行包装,使用了修饰设计器设计模式,不会直接与数据源相连

4.2 处理流的功能主要体现在以下两方面

  • 性能的提高 : 主要以增加缓冲的方式来提高输入输出效率
  • 操作的便捷: 处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活

image-20240110202957171

5. 序列化 和 反序列化

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

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

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

    Serializable 这是一个标记接口

    Externlizable 该接口有方法需要实现,一般实现上面的

细节

  • 读写顺序一致
  • 要求实现序列化和反序列化的对象,需要实现 Serializable
  • 序列化的类中建议添加 SerialVersionUID 为提高版本的兼容性
  • 序列化对象时,默认将里面的所有属性都进行序列化,但除了 static 或 transient 修饰的成员
  • 序列化对象时,要求里面的属性类型也实现序列化接口
  • 序列化具备可继承性,也就是如果某类已经实现了序列化,则他的所有子也默认实现序列化

Properties

image-20240125222938281

  • 专门用来读取配置文件的集合类

​ 配置文件格式

​ 键=值

  • 注意:键值对不需要有空格,值不需要用引号引起来,默认类型就是 String

Properties 的常见方法

  1. load: 加载配置文件到 Properties 对象
  2. list : 将数据显示在指定设备
  3. getProperty(key) 根据键获取值
  4. setProperty(key, value) 设置键值对到 Properties 对象
  5. store 将 Properties 中的键值对存储在配置文件,在 idea 中,保存信息到配置文件,如果含有中文,会存储为unicode

http://tool.chinaz.com/tools/unicode.aspx unicode 码查询工具

posted @ 2024-01-26 20:24  TomLove  阅读(19)  评论(0)    收藏  举报