【JavaEE】文件操作(二):流对象的文件内容操作、文件基础(二):数字&码表&缓冲区

文章目录

一、文件基础(二):数字&码表&缓冲区

1.辨别"输入/输出"

2.数字

2.1形式

2.1.1二进制

2.2类型

2.2.1符号子类型

2.2.1.1有符号数

2.2.1.2无符号数

3.码表

4.缓冲区

4.1作用

4.2实现

4.2.1内存变量

4.2.2缓冲区流对象

二、文件操作(二):流对象的文件内容操作

1.打开文件

1.1字节流

[1.1.1输入流new FileInputStream(file)](#1.1.1输入流new FileInputStream(file))

1.1.1.1read():int

[1.1.1.2read(byte[] b, int off, int len):int](#1.1.1.2read(byte[] b, int off, int len):int)

[1.1.1.3read(byte b[]):int](#1.1.1.3read(byte b[]):int)

[1.1.2输出流new FileOutputStream(file, boolean)](#1.1.2输出流new FileOutputStream(file, boolean))

[1.1.2.1write(int b):void](#1.1.2.1write(int b):void)

[1.1.2.2write(byte[] b, int off, int len):void](#1.1.2.2write(byte[] b, int off, int len):void)

[1.1.2.3write(byte[] b):void](#1.1.2.3write(byte[] b):void)

1.2字符流

[1.2.1输入流new FileReader(file)](#1.2.1输入流new FileReader(file))

1.2.1.1read():int

[1.2.1.2read(char[] cbuf, int off, int len):int](#1.2.1.2read(char[] cbuf, int off, int len):int)

[1.2.1.3read(char[] cbuf):int](#1.2.1.3read(char[] cbuf):int)

[1.2.1.4read(CharBuffer target):int](#1.2.1.4read(CharBuffer target):int)

[1.2.2输出流new FileWriter(file, boolean)](#1.2.2输出流new FileWriter(file, boolean))

[1.2.2.1write(int b):void](#1.2.2.1write(int b):void)

[1.2.2.2write(char[] cbuf, int off, int len):void](#1.2.2.2write(char[] cbuf, int off, int len):void)

[1.2.2.3write(char[] cbuf):void](#1.2.2.3write(char[] cbuf):void)

[1.2.2.4write(String str, int off, int len):void](#1.2.2.4write(String str, int off, int len):void)

[1.2.2.5write(String str):void](#1.2.2.5write(String str):void)

2.关闭文件

2.1文件泄露

2.1.1危害

2.2绑定关闭

2.2.1try{new}finally{close}

2.2.2try(new){}


一、文件基础(二):数字&码表&缓冲区

知识连接:文件基础(一):资源/组织/路径/存储

1.辨别"输入/输出"

站以 cpu/内存****视角

| 输入 | 硬盘输入 内容 来cpu/内存 给读取 |

输出 cpu/内存输出 内容 硬盘写入

2.数字

2.1形式

形式 前缀 含数
二进制 0b 0 ~ 1
十进制 0 ~ 9
八进制 0o或0 0 ~ 7
十六进制 0x 0 ~ f(大小写等价)

|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 2/8/16 => 10 | |
| 10 => 2/816 | 十进制的首次被除数与接下来的商 / 进制 直到商为0余数取完反连 |
| 16 <=> 2 | 1个十六进制数 = 4个二进制数 = 4个bit位(16 = 2^4) |
| 8 <=> 2 | 1个八进制数 = 3个二进制数 = 3个bit位(8 = 2^3) |
[之间转化]

2.1.1二进制

数字的二进制01形式是 计算机读写计量的 操作实体


2.2类型

数字类型 关键字 内存占用 范围
字节型 byte 1 字节 -128 ~ 127
短整型 short 2 字节 -32768 ~ 32767
整型 int 4 字节 -2^31 ~ (2^31) - 1
长整型 long 8 字节 -2^63 ~ (2^63) - 1
单精度浮点数 float 4 字节 -3.4×10³⁸ ~ 3.4×10³⁸(有效位数 6~7 位)
双精度浮点数 double 8 字节 -1.8×10³⁰⁸ ~ +1.8×10³⁰⁸(有效位数 15~17 位)
[基本类型]
非数字类型 关键字 内存占用 范围
字符型 char 2 字节 0 ~ 65535
布尔型 boolean 没有明确规定(1字节) true 和 false
2.2.1符号子类型

Java的数字类型不再割分有无符号 的子类型,数字类型全部都是无符号的

数字类型有无符号的差别 在它们的二进制形式中 玲琳体现出来:

2.2.1.1有符号数

有符号数的首位是符号位,byte的有符号类型 的8位的二进制形式 - 1个bit符号位、7个bit数值位:

  1. min:++1++0000000 = -128
  2. max:++0++1111111 = +127

-127的原码:11111111, 补码:10000001

-127 - 1 = -128的补码:10000000, 原码:++1++0000000 -> 形式-0但意义值是-128

0的原码:++0++0000000 -> 0已经用+0表示了

可以表示 十进制下**-128~127**的256个 数:负数128个 + 零1个 + 正数127个 = 2^7 + 1 + 2^7-1 = 2^7 * 2 = 2^8 = 256个 数


2.2.1.2无符号数

无符号数的全位是数值位,byte的无符号类型 的8位的二进制形式 - 8个bit数值位:

  1. min:00000000 = 0
  2. max:11111111 = 255

可以表示 十进制下0~255的256个 数:零1个 + 正数256个 = 1 + 2^8-1 = 2^8 = 256个 数


3.码表

码表 由 数字互键字符 的两个字段组成:

数字 字符
同一个数的++二进制01形式++是 计算机读写计量的操作实体 ++常在表间关联++
[码表]

4.缓冲区

缓冲区是 内存里的 临时存储区域,本质是 用空间换时间

4.1作用

缓冲区 攒存 开一次****内存<->外设 通道 去交互的 更多数据

  • 存数据在缓冲区 每次向外通道多写
  • 存数据在缓冲区 每次向内通道多读

减少了 内外交互数据去开通道的总次 带来的 外设响应的时间开销系统调用的cpu内核-用户态的切换开销


4.2实现

4.2.1内存变量

内存中手动创建 缓冲区变量 攒存交互


4.2.2缓冲区流对象

传流对象参 向下构造 创建 扩展的自带缓冲区流对象

java 复制代码
BufferedStream bufferedstream = new BufferedStream(stream);

二、文件操作(二):流对象的文件内容操作

知识连接:文件操作(一):文件系统操作

1.打开文件

创建流对象打开文件 读写操作 流储在文件描述符表的内容流

1.1字节流

文件内容 以字节单位地流;不参照码表:直接读写 二进制字节

1.1.1输入流new ++File++InputStream(file)
java 复制代码
InputStream inputStream = new FileInputStream(file);

流对象 直接读取 在文件描述符表文件流出字节流

1.1.1.1read():int
java 复制代码
int data = inputStream.read();
  1. 读取****一个 整字节 的8个二进制01数
  2. 等价成 1个0~256在int范围的十进制数 返回
  3. 等到 读取完字节/读取到内容流末尾/抛出异常 结束

1.1.1.2read(byte[] b, int off, int len):int
java 复制代码
byte[] b = new byte[1024];
int n = inputStream.read(b,0,1024);
  1. 读取 指定个 整字节 的二进制01数 放在外面的字节数组的指定部分
  2. 返回 实际读整的字节个数
  3. 等到 读取完字节/读取到内容流末尾/抛出异常 结束

操作文件指针端 不能自选位置


1.1.1.3read(byte b[]):int
java 复制代码
byte[] data = new byte[1024];
int n = inputStream.read(data);//从字节数组偏移量0位置开始放 读取的数组长度个的字节
  1. 读取 字节数组长度个 整字节 的二进制01数 放在外面的全部字节数组
  2. 返回 实际读整的字节个数
  3. 等到 读取完字节/读取到内容流末尾/抛出异常 结束

方法出值

方法内部可用 引用外存return返回 出值


1.1.2输出流new ++File++OutputStream(file, boolean)
java 复制代码
OutputStream outputStream = new FileOutputStream(file, boolean);

流对象 直接写入 在文件描述符表文件流入字节流

1.1.2.1write(int b):void
java 复制代码
outputStream.write(97);

写入 整体等价用1个0~256在int范围的十进制数表示的 一个整字节8个二进制01数


1.1.2.2write(byte[] b, int off, int len):void
java 复制代码
byte[] bytes = {97,98,99};
outputStream.write(bytes,0,3);

写入 字节数组的指定部分 的整字节的二进制01数


1.1.2.3write(byte[] b):void
java 复制代码
byte[] bytes = {97,98,99};
outputStream.write(bytes);//从字节数组偏移量0位置开始取 写入的数组长度个的字节

写入 全部字节数组 的整字节的二进制01数
写文件

  1. 文件不存在
    文件不存在 打开会创建文件 全新写(创建文件后 清空与追加 结果都是全新写)

文件存在
2.1清空写
文件存在 打开会清空内容 空白写

java 复制代码
OutputStream outputStream = new FileOutputStream(file/*, false*/);
Writer writer = new FileWriter(file/*, false*/);

2.2追加写
文件存在 打开会追加内容 往后写

java 复制代码
OutputStream outputStream = new FileOutputStream(file, true);
Writer writer = new FileWriter(file,true);

1.2字符流

文件内容 以字符单位地流参照码表字符的字节 -> 再字节的字符字符的字节 -> 再字节的字符

码表的参照

  1. FileReader/FileWriter 默认参照 系统编码

    java 复制代码
    // 文件test.txt是UTF-8编码,系统默认编码是GBK编码
    
    try (FileReader fr = new FileReader("test.txt")) {
        char[] chars = new char[1024];
        int len = fr.read(chars); //1.默认使用GBK码表读UTF8文件的字节、默认使用GBK码表取字节对应字符 -> 读乱码
        String content = new String(chars, 0, len);
        System.out.println(content);
    }
    try (FileWriter fw = new FileWriter("test.txt")) {
        String content = "Hello World";
        fw.write(content); //2.默认使用GBK码表写UTF8文件的字节、默认使用GBK码表入字节对应字符 -> 写乱码
        System.out.println("FileWriter写入完成(默认GBK编码)");
    }

InputStreamReader/OutputStreamWriter 手动参照 指定编码

java 复制代码
try (FileInputStream fis = new FileInputStream("test.txt");
     InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8)) { //3.指定使用UTF8码表
    char[] chars = new char[1024];
    int len = isr.read(chars); //正确读字符
    String content = new String(chars, 0, len);
    System.out.println(content);
}
try (FileOutputStream fos = new FileOutputStream("test.txt");
     OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) { //4.指定使用UTF8码表
    osw.write("Hello World"); //正确写字符
}
1.2.1输入流new ++File++Reader(file)
java 复制代码
Reader reader = new FileReader(file);

流对象 参照码表读取 在文件描述符表文件流出字符流

1.2.1.1read():int
java 复制代码
int data = reader.read();
  1. 参照码表 读****一个字符的字节量 二进制01数
  2. 等价成1个0~256在int范围的十进制数返回 ---> 参照码表 取****数字对应的字符
  3. 等到 读取完字符/读取到字节流末尾/发生IO错误 结束

1.2.1.2read(char[] cbuf, int off, int len):int
java 复制代码
char[] cbuf = new char[1024];
int n = reader.read(cbuf,0,1024);
  1. 参照码表 读****指定个字符的字节量 二进制01数 ---> 参照码表 取****数字对应的字符 存出放到****字符数组的指定部分
  2. 返回 实际读取的字符个数
  3. 等到 读取完字符/读取到字节流末尾/发生IO错误 结束

1.2.1.3read(char[] cbuf):int
java 复制代码
char[] cbuf = new char[1024];
int n = reader.read(cbuf); //从字符数组偏移量0位置开始放 读取的数组长度个的字符
  1. 参照码表 读****字符数组长度个字符的字节量 二进制01数 ---> 参照码表 取****数字对应的字符 存出放到****全部字符数组
  2. 返回 实际读取的字符个数
  3. 等到 读取完字符/读取到字节流末尾/发生IO错误 结束

1.2.1.4read(CharBuffer target):int

存放的CharBufferchar[]的封装

1.2.2输出流new ++File++Writer(file, boolean)
java 复制代码
Writer writer = new FileWriter(file, true);

流对象 参照码表写入 在文件描述符表文件流入字符流

1.2.2.1write(int b):void
java 复制代码
writer.write(97);

整体等价用1个0~256在int范围的十进制数表示的 一个整字节 8个二进制01数 ---> 参照码表 数字对应的字符


1.2.2.2write(char[] cbuf, int off, int len):void
java 复制代码
char[] cbuf = new char[3]; cbuf[0] = 'a'; cbuf[1] = 'b'; cbuf[2] = 'c';
writer.write(cbuf,0,3);

参照码表 字符数组的指定部分 的每个字符对应数字 二进制01数 ---> 参照码表 每个数字对应的字符


1.2.2.3write(char[] cbuf):void
java 复制代码
char[] cbuf = new char[3]; cbuf[0] = 'a'; cbuf[1] = 'b'; cbuf[2] = 'c';
writer.write(cbuf); //从字符数组偏移量0位置开始取 写入的数组长度个的字符

参照码表 全部字符数组 的每个字符对应数字 二进制01数;参照码表 每个数字对应的字符


1.2.2.4write(String str, int off, int len):void
java 复制代码
String str = "abc";
writer.write(str,0,3);

写入的String****等价于char[]


1.2.2.5write(String str):void
java 复制代码
String str = "abc";
writer.write(str);

写入的String等价于 char[]


2.关闭文件

java 复制代码
stream.close();

调用流对象关闭文件 回收销毁 ++存储内容流的文件描述符表++

2.1文件泄露

打开文件 使用资源结束 后,不关闭回收 文件 就在泄露文件资源

2.1.1危害

文件资源 无用地占据着在外

  1. 泄减供使用的内部资源
  2. 露增无故修改资源的权限

内存自动回收

Java的内存不需要手动回收JVM封装 好了 自动管理内存回收的GC,++不会发生内存泄露的情况++


2.2绑定关闭

文件有去打开 就必执关闭捆绑执行写法:

2.2.1try{new}finally{close}
java 复制代码
InputStream inputStream = null;
try {
    inputStream = new FileInputStream("./test.txt");
    throw new IOException();
    return;
} finally {
    inputStream.close();
}

2.2.2try(new){}
java 复制代码
try (InputStream inputStream = new FileInputStream("./test.txt")) {
    throw new IOException();
    return;
} finally {
    inputStream.close();
}

try()里面创建 实现Closeable接口 的 流对象的实例,**出代码块{}**后 JVM会调用Closeable接口变量的close方法 转型执行关闭


点个关注再走呗(^_^)☆

相关推荐
Pocker_Spades_A1 个月前
飞算Java在线学生成绩综合统计分析系统的设计与实现
java·开发语言·java开发·飞算javaai炫技赛
cike_y2 个月前
JavaBean&MVC三层架构
java·架构·mvc·javaweb·java开发
中文很快乐2 个月前
java开发--开发工具全面介绍--新手养成记
java·开发语言·java开发·开发工具介绍·idea开发工具
蛐蛐蜉蝣耶2 个月前
Spring AI与MCP集成实践:构建智能应用的新方式
人工智能·微服务·java开发·spring ai·mcp
龙智DevSecOps解决方案2 个月前
Java开发基础:什么是Spring Boot?一文了解其优势、对比以及如何通过Perforce JRebel实现高效开发
java·开发语言·spring boot·jrebel·perforce·java开发
编程火箭车2 个月前
【Java SE 基础学习打卡】19 运算符(中)
java·java入门·运算符·编程基础·赋值运算符·复合赋值·自增自减
小坏讲微服务2 个月前
Spring Boot 4.0 与 MyBatis Plus 整合完整指南
java·spring boot·后端·mybatis·springcloud·mybatis plus·java开发
编程火箭车2 个月前
【Java SE 基础学习打卡】15 分隔符、标识符与关键字
java·java入门·标识符·关键字·编程基础·分隔符·语法规则