Java基础---IO知识以及常用的API整理

       Java 中的 I/O(输入/输出)是一个核心概念,涉及数据的读取和写入。Java I/O API 提供了丰富的类和接口,用于处理不同类型的数据流。了解 Java I/O 的基础知识对于面试和日常编程都非常重要。所以今天来整理一下:

1. File类

      File类主要是JAVA为文件的操作(如增删改查)而设计的相关类,它的包名是java.io,其实现了Serializable, Comparable两大接口以便于其对象可序列化和比较,是文件和目录路径名的抽象表示。

1.1. 常用API

构造方法:

方法名称

说明

File(String pathname)

通过将给定的路径名,字符串转换为抽象路径名来创建新的File实例

File(String parent,String child)

从父路径名,字符串和子路径名,字符串创建新的File实例

File(File parent,String child)

从父抽象路径名和子路径名,字符串创建新的File实例

常用方法

方法作用
创建方法
boolean createNewFile()创建新的文件,如果文件已存在则失败返回false
boolean mkdir()创建这个路径的文件夹
boolean mkdirs()创建路径中所有不存在的文件夹
判断方法
boolean isDirectory()判断是不是文件夹
boolean isFile()判断是不是文件
boolean exists()判断是否存在
获取方法
String getAbsolutePath()获取绝对路径
String getName()获取文件或者文件夹的名称
String getPath()获取文件或者文件夹的路径
String[] list()获取目录下所有的内容--名称
File[] listFiles()获取目录下所有的文件 
删除方法
boolean delete()删除文件或者文件夹
void deleteOnExit()删除存在的文件或者文件夹

2. I/O流

2.1. 概念

        IO中的 I 是指Input(输入,指的是读取数据),O 是指Output(输出,指的是写数据);流是一种抽象概念,是对数据传输的总称,也就是说数据在设备间的传输称为流,流的本质是数据传输,常应用于文件上传、下载、复制等。

2.2. 分类

a. 根据数据流向分类:

  1. 输入流:读数据  将硬盘中的数据读取到内存中
  2. 输出流:写数据  将程序中的数据写入到硬盘中

b. 按照数据类型来分

字节流 字节输入流/字节输出流

字符流 字符输入流/字符输出流

2.3. 应用场景

1.纯文本文件,优先使用字符流

2.图片、视频、音频等二进制文件优先使用字节流

3.不确定文件类型,优先使用字节流字节流是万能的流

3. 具体API的使用

3.1. OutputStream 输出流

       OutputStream是抽象类,表示字节输出流的所有类的超类;子类名称都是以其父类名作为子类名的后缀。

3.1.1. FileOutputStream 文件输出流

文件输出流用于将数据写入File,有三种写入方式:

方法名称

说明

void write(int b)

将指定的字节写入此文件输出流 一次写一个字节数据

void write(byte[] b)

将 b.length字节从指定的字节数组写入此文件输出流 一次写一个

字节数组数据

void write(byte[] b, int st, int len)

从st下标开始,写入长度为len的数据

以下是代码演示:

public class OutputStreamAPI {

    public static void main(String[] args) throws IOException {
        //指定写入的路径
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\学习资料\\test.txt");
        //写入到磁盘中
        byte[] bytes = new byte[]{95,96,97,98};
        fileOutputStream.write(bytes,2,1);
//        关闭字节输出流
        fileOutputStream.close();
    }
    
}

字节流写入数据如何换行?

windows:\r\n

linux:\n

mac: \r

3.2. InputStream 输出流

       InputStream是抽象类,表示字节输入流的所有类的超类;子类名称都是以其父类名作为子类名的后缀。

3.2.1. FileInputStream 文件输入流

我们可以通过FileInputStream读取磁盘文件中的数据,使用read()方法读取,每次读取一个字节。

public class InputStreamAPI {
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\学习资料\\test\\aaa.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        int a ;
        while ((a = fileInputStream.read()) != -1){
            System.out.print((char)a);
        }
        fileInputStream.close();
    }
}

使用以上两个流,我们便可以实现文件的拷贝了,我们可以使用FileInputStream来读取文件中的字节,然后使用FileOutputStream来写入新的文件,实现拷贝功能,以下是代码:

public class FileCopy {
    public static void main(String[] args) throws IOException {
        File file1 = new File("E:\\学习资料\\test\\aaa.txt");
        File file2 = new File("E:\\学习资料\\test\\bbb.txt");
        FileInputStream fileInputStream = new FileInputStream(file1);
        FileOutputStream fileOutputStream = new FileOutputStream(file2);
        int BYTE = fileInputStream.read();
        while(BYTE != -1){
            fileOutputStream.write(BYTE);
            BYTE = fileInputStream.read();
        }
        fileInputStream.close();
        fileOutputStream.close();
    }
}

3.3. 字节缓冲流

前面的方式是一个字节、一个字节读取或者写入数据,会频繁的发生系统内核调用(用户态内核态切换)效率非常低。因此可以使用字节缓冲流,缓冲区是一个内存区域的概念,类似于池子“块的形似写入或者读取数据 减少系统调用频率。

BufferedInputStream(InputStream in):字节缓冲输入流

BufferedOutputStream(OutputStream out):字节缓冲输出流

构造函数传递字节流对象,不是文件路径,缓冲流提供了一个缓冲区 做了封装以块的形式读写数据,读写数据还是依赖于字节流对象。

注意:字节缓冲流的缓冲区大小默认是8K,即:8192字节

package JavaIO;

import java.io.*;

/**
 * @Author: stukk
 * @Description: 使用字节缓冲输出流于不适用的对比
 * @DateTime: 2024-02-02 23:41
 **/
public class BufferedStreamAPI {
    public static void main(String[] args) throws IOException {
//         执行缓存程序耗时:549ms
//        执行单个字节复制的程序耗时:3300ms
        long start = System.currentTimeMillis();
        buffer(); //使用缓存的
        long end = System.currentTimeMillis();
        System.out.println("执行缓存流程序耗时:"+(end - start)+"ms");
        start = System.currentTimeMillis();
        single();
        end = System.currentTimeMillis();
        System.out.println("执行单个字节流传输程序的耗时:"+(end - start)+"ms");
    }

    private static void buffer() throws IOException {
        //        读取
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:\\学习资料\\1\\test.mp4"));
//        写
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("E:\\学习资料\\2\\newTest.mp4"));
        int len;
        byte[] bytes = new byte[1024]; //读取的块
        while((len = bufferedInputStream.read(bytes)) != -1){
            bufferedOutputStream.write(bytes,0,len);
        }
        bufferedOutputStream.flush();
        bufferedInputStream.close();
        bufferedOutputStream.close();
    }


    private static void single() throws IOException {
        //        读取
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:\\学习资料\\1\\test.mp4"));
//        写
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("E:\\学习资料\\3\\newTest.mp4"));
        int len;
        while((len = bufferedInputStream.read()) != -1){
            bufferedOutputStream.write(len);
        }
        bufferedOutputStream.flush();
        bufferedInputStream.close();
        bufferedOutputStream.close();
    }


}

3.4. 字符流

3.4.1. 编码问题

1.当字节流读取存储中文数据时可能会乱码,我们可以使用字符流。

字符流=字节流+编码表

2.编码表:可以看做是一个字典,这本字典翻译是 人类的字符 和 机器语言(二进制) 之间对应关系。

3.编码表(ASCⅡ):就是人类生活的字符和计算机二进制的对照关系表。例如a 97

4.ISO8859-1:欧洲制定的码表。兼容ASCII。多了一些欧洲的语言。它用1个字节的全部来表示数据。没有未知字符的!

5.GB2312:识别数千中文

6.GBK:识别2万多中文,2个字节表示一个字符。

7.GB18030:GBK的升级

8.Unicode:世界计算机协会制定通用码表,2个字节表示一个字符。

9.UTF-8:Unicode升级版,汉字基本都是3个字节 推荐使用

3.4.2. 字符流详细介绍

字符流主要是应用在文本的输入以及输出中,指定文本的编码以及解码。

1.Writer是写入字符流的抽象类

1.1.OutputStreamWriter(输出转换流)是字符流通向字节流的桥梁,将要写入流的字符编码成字节。构造方法摘要OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。1.2.OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。

字符流的底层还是用字节流进行读写,字符流仅仅是做了字节和字符的转换(编码和解码)。接收一个字节流,形成了字符流。把字节流转换为字符流!接收字符数据,首先要把字符数据变成字节数据,然后再用普通字节流,把数据写到硬盘。实现了字符数据转换为字节数据。

2.Reader是用于读取字符流的抽象类

2.2.InputStreamReader(输入转换流)是字节流通向字符流的桥梁,将要读取字节并将其解码成字符。

构造函数:InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader(InputStream in, String charsetName)创建使用指定字符集的 InputStreamReader。

字符流底层还是用的字节流,字符流仅仅做字符和字节的转换!接收一个字节流,生成的一个字符流。把字节流转换为字符流。底层会用字节流去硬盘读取字节数据,把字节数据转换为字符数据,然后返回。实现了把字节数据转换为字符数据。

字符流---读写操作:

package JavaIO;

import java.io.*;

/**
 * @Author: stukk
 * @Description: 字符流 读写操作
 * @DateTime: 2024-02-05 17:13
 **/
public class OutputStreamWriterAPI {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\学习资料\\test.txt"),"GBK");
        outputStreamWriter.write("stukk\n坤坤");
        outputStreamWriter.close();
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\学习资料\\test.txt"),"GBK");
        char[] chars = new char[1024];
        int len = inputStreamReader.read(chars);
        System.out.println(new String(chars,0,len));
    }

}

5种写入的方式:

方法名称

功能

public void write(int c)

写出一个字符

public void write(char[] cbuf)

写出字符数组

public void write(char[] cbuf,int off,int len)

写出字符数组cbuf中,从off开始,共len个字符

public void write(String str)

写出字符串

 public void write(String str,int off,int len)

写出字符串,从off开始,共len个字符

读取方法

方法名称

功能

int read()

一次读一个字符数据

int read(char[] cbuf)

一次读一个字符数组数据

3.5. 字符缓冲流

1.BufferedReader:从字符输入流读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

BufferReader:默认缓存大小为8k,但可以手动指定缓存大小,把数据读取到缓存中,减少每次转换过程,效率更高 

2.BufferedWriter: 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

BufferWriter:默认缓存大小为8k,但可以手动指定缓存大小,把数据读取到缓存中,减少每次转换过程,效率更高

BufferedWriter-字符缓冲写入流

BufferedReader-字符缓冲输入流

Api设计思想与前面的字节缓冲流思想一样。

以下是拷贝文件的例子:

private static void buffer() throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\学习资料\\test.java"));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\学习资料\\ok.java"));
        String s = null;
        while((s = bufferedReader.readLine()) != null){
            bufferedWriter.write(s);
            bufferedWriter.newLine();
        }
        bufferedWriter.close();
        bufferedReader.close();
    }

3.6. 转换流的便捷形式:FileWriter和FileReader

前面的:
new InputStreamReader(new FileInputStream("文件路径")); 
可以替换成:
new FileReader("文件路径");
同理,FileWrite也是一样

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/373037.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

day42_jdbc

今日内容 0 复习昨日 1 JDBC概述 2 JDBC开发步骤 3 完成增删改操作 4 ResultSet 5 登录案例 0 复习昨日 1 写出JQuery,通过获得id获得dom,并给input输入框赋值的语句 $(“#id”).val(“值”) 2 mysql内连接和外连接的区别 内连接只会保留完全符合关联条件的数据 外连接会保留表…

LeetCode、746. 使用最小花费爬楼梯【简单,动态规划 线性DP】

文章目录 前言LeetCode、746. 使用最小花费爬楼梯【简单,动态规划 线性DP】题目与分类思路 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。…

idea 快捷键ctrl+shift+f失效的解决方案

文章目录 搜狗输入法快捷键冲突微软输入法快捷键冲突 idea的快捷键ctrlshiftf按了没反应,理论上是快捷键冲突了,检查搜狗输入法和微软输入法快捷键。 搜狗输入法快捷键冲突 不需要简繁切换的快捷键,可以关闭它,或修改快捷键。 微…

Linux Shell编程系列--开篇

一、目的 从本篇开始介绍Linux Shell脚本编程,为简单起见,本篇中以一个显示当前时间的shell脚本来帮助大家理解shell脚本的组成。 SHELL脚本中可以包含变量、函数、命令等部分。 二、介绍 我们通过vim新建一个myshell.sh的脚本,然后输入以下…

工作与生活平衡:在生活中寻找和谐

工作和生活是我们生活中不断交织的两个重要方面。对许多人来说,找到两者之间的完美平衡已经成为一个持久的挑战。然而,与其专注于平衡,更重要的是要认识到工作和生活并不是可以相互平衡的两个分离实体,而是一个相互影响的循环。正…

C++之程序内存分配方式

程序内存布局 现在的应用程序都运行在一个虚拟内存空间里,以32位系统为例,其寻址空间为 4G,大部分的操作系统都将4G内存空间的一部分挪给内核调用,应用程序无法直接 访问这一段内存,这一部分内核地址成为内核态空间&am…

LeetCode:13.罗马数字转整数

13. 罗马数字转整数 - 力扣(LeetCode) 目录 思路: 官解代码: 作者辣眼代码: 每日表情包: 思路: 思路已经很明了了,题目已经给出一般规则和特殊规则(而且题目确保给定的是正确的…

利用 ASP.NET Core 开发单机应用

前言 现在是分布式微服务开发的时代,除了小工具和游戏之类刚需本地运行的程序已经很少见到纯单机应用。现在流行的Web应用由于物理隔离天然形成了分布式架构,核心业务由服务器运行,边缘业务由客户端运行。对于消费终端应用,为了应…

Nginx使用详解

简介Nginx的优缺点Nginx的应用场景Nginx支持的模块Nginx模块配置示例1. **HTTP Access Log 模块**2. **HTTP SSL 模块**3. **HTTP Gzip 模块**4. **HTTP Rewrite 模块** Nginx支持的反向代理协议Nginx反向代理配置Nginx反向代理优点Nginx反向代理配置示例Nginx常用配置参数Ngin…

一文搞懂 springboot 如何融合数据源

1、简介 springboot 支持关系型数据库的相关组件进行配置,包括数据源、连接池、事务管理器等的自动配置。降低了数据库使用的难度,除了 mysql 还支持 Derby、H2等嵌入式数据库的自动配置,MongoDB、Redis、elasticsearch等常用的 NoSQL 的数据…

uWSGI、灰度发布、网站数据指标分析、网站限速

1 案例1:部署Python网站项目 1.1 问题 配置Nginx使其可以将动态访问转交给uWSGI: 1.2 方案 安装Python工具及依赖 安装uWSGI并编写配置文件 1.3 步骤 实现此案例需要按照如下步骤进行。 步骤一: 首先$教学资料目录/python拷贝到虚拟…

Python程序设计 函数

简单函数 函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。 函数的使用包含两个步骤: 定义函数 —— 封装 独立的功能 调用函数 —— 享受 封装 的成果 函数的作用,在开发程序时,使用…

Unity3d Shader篇(一)— 顶点漫反射着色器解析

文章目录 前言一、顶点漫反射着色器是什么?1. 顶点漫反射着色器的工作原理 二、编写顶点漫反射着色器1. 定义属性2. 创建 SubShader3. 编写着色器程序段4. 完成顶点着色器5. 完成片段着色器 三、效果四、总结 前言 在 Unity 中,Shader 可以用来实现各种…

jmeter设置关联

一、为什么要设置关联? http协议本身是无状态的,客户端只需要简单向服务器请求下载某些文件,无论是客户端还是服务端都不去记录彼此过去的行为,每一次请求之间都是独立的。如果jmeter需要设置跨线程组脚本,就必须设置…

【问题篇】activiti工作流转办并处理备注问题

当处理activiti转办问题时,需要做的就是处理审批人和备注问题。 处理的思路是,先将当前环节标志成转办标签,再通过BUSINESS_KEY_找到流程实例的历史记录,找到最新的一条复制一份出来,表示需要转办到的人的历史记录并设…

APP专项测试方法总结

APP专项测试 1、网络测试 可使用抓包工具辅助网格测试推荐:fiddler,Charles 网络切换: 2G-3G-4G-wifi-网络信号差–无网 网络信号弱: 关注是否出现ANR、crash 2、中断测试 意外中断: 来电;短信&am…

不需英文基础也可以轻松学编程,中文编程开发工具免费版下载,编程工具构件箱之扩展控制面板构件用法

不需英文基础也可以轻松学编程,中文编程开发工具免费版下载,编程工具构件箱之扩展控制面板构件用法 一、前言 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 编程工具及实例源码文件下载可以点击最下方官网卡片——软件下载——常…

ShardingSphere 5.x 系列【3】分库分表中间件技术选型

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 前言2. My Cat3. ShardingSphe…

C++ 类与对象(下)

目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2. static成员 2.1 概念 2.2 特性 3.友元 3.1友元函数 3.2 友元类 4. 内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 7. 再次理解类和对象 【本节目标】 1. 再谈构造函数 2. Static成员…

【产品升级】SmartPipe升级到版本2.0

在近一个月的攻关和测试下,SmartPipe软件轴线自动识别算法的性能大幅提升,鲁棒性和稳定性进一步增强。近一年来客户累计反馈的多种复杂管路(包括带有支管管路、带有压瘪段管路、推弯管、装配管、带有复杂孔洞管路等)现在均能够正确…
最新文章