Java I/O流详解

文章目录

I/O流概念

Java I/O(inputStream/outStream)流是Java标准库中用于处理输入和输出操作的一组类和接口。这些类和接口位于 java.io 包中,提供了丰富的功能来处理文件、网络连接、内存数据等。

I/O流的分类

Java I/O流根据传输数据的不同主要分为两大类:字节流和字符流。 下面我们将分别介绍字节流和字符流的区别和应用场景.

字节流(Byte Streams)

顾名思义,字节流主要处理的数据就是字节(Byte),但是很多小伙伴可能不是很清楚字节的概念,下面我们将简单概述一下什么是字节。

字节

字节(Byte)是计算机科学中一个基本的数据单位,用于表示和存储信息。理解字节的概念对于编程、数据传输和存储等方面都是非常重要的。

  • 字节是计算机中最小的地址单位,通常由8个比特(bit) 组成。 其中bit就是计算机存储中的0或者是1,一bit代表一位0或者1。
  • 一个字节可以用8位二进制数表示,例如:01001001。字节也可以用十六进制表示,例如:49(对应二进制 01001001)。
  • 计算机中的所有数据最终都会被表示为字节序列。
    一个字符在ASCII编码中占用1个字节,一个整数在大多数系统中占用4个字节。
    在网络通信和文件传输中,数据通常以字节为单位进行传输。
    例如,HTTP协议中的数据传输是以字节为单位进行的。

了解了字节的概念以后我们接着去了解字节流相关的概念

字节流概述

定义:在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,I/O流中针对字节的输入/输出提供了一系列的流,统称为字节流。

说明:

字节流是程序中最常用的流。

在JDK中,所有的字节输入流都继承自 InputStream,所有的字节输出流都继承自 OutputStream。

方法
  • 读取方法:
    • int read():从输入流中读取一个字节或字符。
    • int read(byte[] b) / int read(char[] cbuf):从输入流中读取一定数量的字节或字符,并存储到数组中。
    • String readLine():从字符输入流中读取一行文本(BufferedReader 特有)。
  • 写入方法:
    • void write(int b):将一个字节或字符写入输出流。
    • void write(byte[] b) / void write(char[] cbuf):将字节数组或字符数组写入输出流。
    • void write(String str):将字符串写入输出流(Writer 特有)。
  • 关闭方法:
    • void close():关闭输入流或输出流,并释放与之关联的系统资源。
主要类和继承关系
  • InputStream:字节输入流的基类。

    • FileInputStream:从文件中读取字节。
    • ByteArrayInputStream:从字节数组中读取字节。
    • ObjectInputStream:从字节流中读取对象。
    • FilterInputStream:装饰器模式,用于添加额外功能的输入流。
      • BufferedInputStream:带缓冲的输入流,提高读取效率。
      • DataInputStream:从输入流中读取基本数据类型(如整数、浮点数等)。
  • OutputStream:字节输出流的基类。

    • FileOutputStream:将字节写入文件。
    • ByteArrayOutputStream:将字节写入字节数组。
    • ObjectOutputStream:将对象写入字节流。
    • FilterOutputStream:装饰器模式,用于添加额外功能的输出流。
      • BufferedOutputStream:带缓冲的输出流,提高写入效率。
      • DataOutputStream:将基本数据类型写入输出流。
示例代码
java 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamExample {
    public static void main(String[] args) {
        String inputFilePath = "input.txt";
        String outputFilePath = "output.txt";

        try (
            FileInputStream fis = new FileInputStream(inputFilePath);
            FileOutputStream fos = new FileOutputStream(outputFilePath)
        ) {
            int byteRead;
            while ((byteRead = fis.read()) != -1) {
                fos.write(byteRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意的是针对FileInputStream和FileoutputStream这种类需要加入try-catch进行捕获IO异常。

字节流读取文件

说明:

  • 针对文件的读写操作,JDK专门提供了两个类,分别是 FileInputStream 和 FileOutputStream。
  • FileInputStream 是 InputStream 的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。
  • 从文件读取数据是重复的操作,因此需要通过循环语句来实现数据的持续读取。
字符流

字符流(Character Streams)是Java I/O库中用于处理文本数据的一组类。字符流以字符为单位进行读写操作,通常用于处理文本文件。与字节流相比,字符流具有更好的可读性和易用性,因为它们直接处理字符而不是字节,并且支持多种字符编码。

字符流概述

相较于字节流处理所有的文件,文件流只能用与处理文本数据,也就是我们所说的txt文件,其中也和字节流的形式差不多,都是拥有输入流和输出流,但是他们的基类有差距,分别是Reader 类和Write类.

子类
Reader

Reader 是所有字符输入流的基类,提供了一些基本的方法来读取字符数据。主要子类包括:

1.FileReader:
  • 从文件中读取字符。
  • 示例:
java 复制代码
import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {
    public static void main(String[] args) {
        String filePath = "input.txt";  // 文件路径

        try (FileReader fr = new FileReader(filePath)) {
            int charRead;
            while ((charRead = fr.read()) != -1) {
                System.out.print((char) charRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
2.CharArrayReader:
  • 从字符数组中读取字符。
  • 示例:
java 复制代码
import java.io.CharArrayReader;
import java.io.IOException;

public class CharArrayReaderExample {
    public static void main(String[] args) {
        char[] data = {'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'};

        try (CharArrayReader car = new CharArrayReader(data)) {
            int charRead;
            while ((charRead = car.read()) != -1) {
                System.out.print((char) charRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
3.StringReader:
  • 从字符串中读取字符。
  • 示例:
java 复制代码
import java.io.StringReader;
import java.io.IOException;

public class StringReaderExample {
    public static void main(String[] args) {
        String data = "Hello, World!";

        try (StringReader sr = new StringReader(data)) {
            int charRead;
            while ((charRead = sr.read()) != -1) {
                System.out.print((char) charRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4.InputStreamReader:
  • 将字节输入流转换为字符输入流,支持多种字符编码。
  • 示例:
java 复制代码
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;

public class InputStreamReaderExample {
    public static void main(String[] args) {
        String filePath = "input.txt";  // 文件路径

        try (FileInputStream fis = new FileInputStream(filePath);
             InputStreamReader isr = new InputStreamReader(fis, "UTF-8")) {
            int charRead;
            while ((charRead = isr.read()) != -1) {
                System.out.print((char) charRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
5.BufferedReader:
  • 带缓冲的字符输入流,提高读取效率,支持按行读取。
  • 示例:
java 复制代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {
    public static void main(String[] args) {
        String filePath = "input.txt";  // 文件路径

        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
7.LineNumberReader:
  • 带行号的字符输入流,继承自 BufferedReader,支持按行读取并记录行号。
  • 示例:
java 复制代码
import java.io.LineNumberReader;
import java.io.FileReader;
import java.io.IOException;

public class LineNumberReaderExample {
    public static void main(String[] args) {
        String filePath = "input.txt";  // 文件路径

        try (LineNumberReader lnr = new LineNumberReader(new FileReader(filePath))) {
            String line;
            while ((line = lnr.readLine()) != null) {
                System.out.println("Line " + lnr.getLineNumber() + ": " + line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Writer 类

Writer 是所有字符输出流的基类,提供了一些基本的方法来写入字符数据。主要子类包括:

1.FileWriter
  • 将字符写入文件。
  • 示例:
java 复制代码
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterExample {
    public static void main(String[] args) {
        String filePath = "output.txt";  // 文件路径
        String content = "Hello, World!";

        try (FileWriter fw = new FileWriter(filePath)) {
            fw.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
2.CharArrayWriter:
  • 将字符写入字符数组。
  • 示例:
java 复制代码
import java.io.CharArrayWriter;
import java.io.IOException;

public class CharArrayWriterExample {
    public static void main(String[] args) {
        String content = "Hello, World!";

        try (CharArrayWriter caw = new CharArrayWriter()) {
            caw.write(content);
            System.out.println(caw.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 3.StringWriter:
  • 将字符写入字符串。
  • 示例:
java 复制代码
import java.io.StringWriter;
import java.io.IOException;

public class StringWriterExample {
    public static void main(String[] args) {
        String content = "Hello, World!";

        try (StringWriter sw = new StringWriter()) {
            sw.write(content);
            System.out.println(sw.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4.OutputStreamWriter:
  • 将字符输出流转换为字节输出流,支持多种字符编码。
  • 示例:
java 复制代码
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;

public class OutputStreamWriterExample {
    public static void main(String[] args) {
        String filePath = "output.txt";  // 文件路径
        String content = "Hello, World!";

        try (FileOutputStream fos = new FileOutputStream(filePath);
             OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")) {
            osw.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
5.BufferedWriter:
  • 带缓冲的字符输出流,提高写入效率,支持按行写入。
  • 示例:
java 复制代码
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterExample {
    public static void main(String[] args) {
        String filePath = "output.txt";  // 文件路径
        String content = "Hello, World!";

        try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
            bw.write(content);
            bw.newLine();  // 写入换行符
            bw.write("This is another line.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
6.PrintWriter:
  • 格式化输出流,支持打印操作,常用于日志记录等。
  • 示例:
java 复制代码
深色版本
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;

public class PrintWriterExample {
    public static void main(String[] args) {
        String filePath = "output.txt";  // 文件路径

        try (PrintWriter pw = new PrintWriter(new FileWriter(filePath))) {
            pw.println("Hello, World!");
            pw.println("This is another line.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总结

字符流:用于处理文本数据,以字符为单位进行读写操作。

Reader 类:提供字符输入流的功能,主要子类包括 FileReader、CharArrayReader、StringReader、InputStreamReader、BufferedReader 和 LineNumberReader。

Writer 类:提供字符输出流的功能,主要子类包括 FileWriter、CharArrayWriter、StringWriter、OutputStreamWriter、BufferedWriter 和 PrintWriter。

通过理解和使用这些类和方法,可以灵活地处理各种文本数据的读写操作,满足不同的应用场景需求。

相关推荐
蓝天星空8 分钟前
spring cloud gateway 3
java·spring cloud
罗政13 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第9章 插件与链路的结合:Mysql插件实现
java·mysql·pdf
一根稻草君19 分钟前
利用poi写一个工具类导出逐级合并的单元格的Excel(通用)
java·excel
kirito学长-Java22 分钟前
springboot/ssm网上宠物店系统Java代码编写web宠物用品商城项目
java·spring boot·后端
木头没有瓜36 分钟前
ruoyi 请求参数类型不匹配,参数[giftId]要求类型为:‘java.lang.Long‘,但输入值为:‘orderGiftUnionList
android·java·okhttp
奋斗的老史36 分钟前
Spring Retry + Redis Watch实现高并发乐观锁
java·redis·spring
high201138 分钟前
【Java 基础】-- ArrayList 和 Linkedlist
java·开发语言
老马啸西风1 小时前
NLP 中文拼写检测纠正论文 C-LLM Learn to CSC Errors Character by Character
java
Cosmoshhhyyy1 小时前
LeetCode:3083. 字符串及其反转中是否存在同一子字符串(哈希 Java)
java·leetcode·哈希算法