详解文件操作和 IO

️ 主页:小夜时雨
️ 专栏:javaEE初阶
️ 如何优雅的活着,是我找寻的方向

目录

  • 一、认识文件
  • 二、文件路径
  • 三、文件系统操作
  • 四、文件内容的操作读写 - 数据流
    • 4.1 InputStream 概述
    • 4.2 OutputStream 概述
    • 4.3 "字符流":Reader Writer

一、认识文件

我们平时谈到的"文件"(file),指的都是硬盘上的文件

  • 硬盘(外存)和 内存的比较
  • 速度:内存比硬盘快很多,几千倍的关系
  • 空间:内存空间比硬盘小
  • 成本:内存比硬盘贵
  • 数据的持久化:内存掉电后数据会丢失。硬盘掉电后数据一直存在。

二、文件路径

对文件的系统管理,就是按照层级结构进行组织 —— 也就是我们数据结构中学习过的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory)的概
念。

  • 绝对路径
  • 从盘符开始,一层一层往下找直到目标文件,寻找过程得到的路径就叫做 绝对路径
  • 相对路径
  • 从给定的某个目录出发(工作目录 / 基准目录),一层一层往下找直到目标文件,这个过程得到的路径就是相对路径。
  • 所以一定要明确好基准目录 / 工作目录
  • 相对路径中 ./ 表示当前路径 ,两个点加 / 表示当前目录的上一级目录
  • 文本文件 vs 二进制文件
  • 文本文件 存储是文本,内容都是有ascii字符或者其他字符集编码构成的,也就是说文件里存储的数据,就是遵守 ascii 或者其他字符集编码所得到的文件
  • 二进制文件 存储的是二进制数据,则没有任何字符集的限制
  • 简单的一种判定方式:直接用记事本打开(是按照文本的方式来解析显示的),如果能看懂就是文本文件,看不懂乱码,则就是二进制文件。
    二进制都是一个一个的字节,记事本尝试把当前若干个字节的数据往 utf8 码表里套,套出来是啥就是啥,套不出来的就是方块
  • 文本文件:.txt .java .c
  • 二进制文件: .class .exe .jpg .mp3 以及word编辑的docx 和 excel 编辑的表格

三、文件系统操作

本段内容中,我们主要涉及文件的元信息、路径的操作,暂时不涉及关于文件中内容的读写操作。

java标准库中,给我们提供了File这个类,File对象是硬盘上的一个文件的"抽象"表示,文件是存储在硬盘上的,直接通过代码操作硬盘不太方便,就在内存中创建了一个对应的对象,操作这个内存中的对象,就可以间接影响到硬盘上的文件情况了~~

  1. 构造File对象

构造的过程中可以使用绝对路径 / 相对路径 进行初始化,这个路径指向的文件可以是真实存在的,也可以是不存在的 ,下图是构造方法:
在这里插入图片描述
2. File提供的方法
详解文件操作和 IO_第1张图片

四、文件内容的操作读写 - 数据流

  • 针对二进制文件,java标准库提供了一组类,统称为"字节流",典型代表为 InputStream OutputStream,读写的基本单位是字节。
  • 针对文本文件,java标准库提供了一组类,统称为"字符流",典型代表为 Reader Writer,读写的基本单位是字符。

4.1 InputStream 概述

方法:

修饰符及返回值类型 方法签名 说明
int read() 读取一个字节的数据,返回 -1 代表已经完全读完了
int read (byte[] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了
int read(byte[] b, int off , int len) 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
void close() 关闭字节流
  • 注意:

关闭文件操作,释放文件资源(文件描述符表)十分重要,不然会造成文件资源泄露,非常严重的后果

详解文件操作和 IO_第2张图片

所以我们采用 try (InputStream is = new FileInputStream(“hello.txt”)) { } 这样的代码
InputStream 实现了一个特定的接口Closeable , 带有资源的 try 操作,会在 try 代码块结束后,自动执行 close 操作,以防止后面忘记写 关闭文件操作 (close() )或者中间出现了异常,导致执行不到关闭文件操作 (close() )

  • 说明:

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本
可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream

  • FileInputStream 概述

构造方法
详解文件操作和 IO_第3张图片
代码实例:

import java.io.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "Hello" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            while (true) {
                int b = is.read();
                if (b == -1) {
                    // 代表文件已经全部读完
                    break;
               }
                
                System.out.printf("%c", b);
           }
       }
   }
}
  • 利用 Scanner 进行字符读取

对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类
在这里插入图片描述

import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
           try (Scanner scanner = new Scanner(is, "UTF-8")) {
               while (scanner.hasNext()) {
                   String s = scanner.next();
                   System.out.print(s);
               }
           }
       }
   }
}

4.2 OutputStream 概述

方法

修饰符及返回值类型 方法签名 说明
void write(int b) 读取一个字节的数据,返回 -1 代表已经完全读完了
void write(byte[] b) 将 b 这个字符数组中的数据全部写入 os 中
int write(byte[] b, int off,int len) 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
void close() 关闭字节流
void flush() 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。
  • 说明
    OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream

代码示例:

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            os.write('H');
            os.write('e');
            os.write('l');
            os.write('l');
            os.write('o');
            // 不要忘记 flush
            os.flush();
       }
   }
}

4.3 “字符流”:Reader Writer

读取的基本单位是字符

详解文件操作和 IO_第4张图片

try (Reader reader = new FileReader("d:/test.txt")  ){  }
try (Writer writer = new FileWriter("d:/test.txt")  )  {  } 

代码示例:

public class IODemo8Reader {
    public static void main(String[] args) {
        //Reader 和 writer 读写的是文本文件,提供了一组类,统称为“字符流”
        try(Reader reader = new FileReader("d:/test.txt")) {
            while(true) {
                int c = reader.read();  //转成ascii码
                if(-1 == c) {
                    break;
                }
                System.out.println(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

️️️ 好啦,到这里有关 文件操作和 IO 的分享就没了,如果感觉做的还不错的话可以点个赞,关注一下,你的支持就是我继续下去的动力,蟹蟹大家了,我们下期再见,拜拜~ ☆*: .。. o(≧▽≦)o .。.:*☆

你可能感兴趣的:(javaEE初阶,开发语言,IO,文件操作,javaEE,后端)