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

本文详细介绍了Java中的I/O操作,包括File类的基本使用、I/O流的分类(字节流与字符流)、具体API的应用(如OutputStream和InputStream),以及编码问题和字符缓冲流的原理和示例。
摘要由CSDN通过智能技术生成

       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也是一样
  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stu_kk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值