Java 入门指南:Java IO流 —— 转换流、扫描流、打印流

转换流

转换流可以将一个 字节流 包装成 字符流,或者将一个字符流包装成字节流。这种转换通常用于处理文本数据,如读取文本文件或将数据从网络传输到应用程序。

转换流主要有两种类型:InputStreamReaderOutputStreamWriter

InputStreamReader 将一个字节输入流转换为一个字符输入流,而 OutputStreamWriter 将一个字节输出流转换为一个字符输出流。它们使用指定的字符集将字节流和字符流之间进行转换。常用的字符集包括 UTF-8、GBK、ISO-8859-1 等。

![[转换流.png]]

为提高读写效率,会在转换流上添加一层缓冲流

在使用转换流时,需要指定正确的字符集编码方式,否则可能会导致数据读取或写入出现乱码。

InputStreamReader

java.io.InputStreamReader 是 Reader 类的子类。它的作用是将字节流(InputStream)转换为字符流(Reader),同时支持指定的字符集编码方式,从而实现字符流与字节流之间的转换。

构造方法
  • InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。

  • InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集(ASCII、Unicode、GBK…)的字符流。

常用方法

InputStreamReader 类的常用方法包括:

  • read():从输入流中读取一个字符的数据。

  • read(char[] cbuf, int off, int len):从输入流中读取 len 个字符的数据到指定的字符数组 cbuf 中,从 off 位置开始存放。

  • ready():返回此流是否已准备好读取。

  • close():关闭输入流。

使用示例

假设有一个字节流 InputStream,需要将其转换为字符流进行读取。

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

public class InputStreamReaderExample {
    public static void main(String[] args) {
        // 假设有一个字节流 InputStream
        InputStream inputStream = getClass().getResourceAsStream("/example.txt");

        try (InputStreamReader isr = new InputStreamReader(inputStream);
             BufferedReader br = new BufferedReader(isr)) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例说明

  • 创建 InputStream:这里使用 getClass().getResourceAsStream() 方法来获取资源文件 example.txtInputStream

  • 创建 InputStreamReader:使用 inputStream 创建一个 InputStreamReader,默认使用系统默认的字符集。

  • 创建 BufferedReader:使用 InputStreamReader 创建一个 BufferedReader,以便逐行读取数据。

  • 读取数据:通过 BufferedReaderreadLine() 方法逐行读取数据,并打印出来。

如果想要指定字符集编码,可以在创建 InputStreamReader 时传递编码名称:

InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8");

OutputStreamWriter

java.io.OutputStreamWriter 是 Writer 的子类,字面看容易误以为是转为字符流,其实是将字符流转换为字节流,是字符流到字节流的桥梁。

构造方法
  • OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。

  • OutputStreamWriter(OutputStream in, String charsetName):创建一个指定字符集的字符流。

常用方法
  • write(int c):向输出流中写入一个字符的数据。

  • write(char[] cbuf, int off, int len):向输出流中写入指定字符数组 cbuf 中的 len 个字符,从 off 位置开始。

  • flush():将缓冲区的数据写入输出流中。

  • close():关闭输出流。

使用示例

假设要将字符数据写入一个字节流 OutputStream

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.IOException;

public class OutputStreamWriterExample {
    public static void main(String[] args) {
        // 假设有一个字节流 OutputStream
        OutputStream outputStream = System.out;  // 这里使用标准输出流

        try (OutputStreamWriter osw = new OutputStreamWriter(outputStream, "UTF-8");
             BufferedWriter bw = new BufferedWriter(osw)) {
            String content = "Hello, World!";
            bw.write(content);
            bw.newLine();  // 写入换行符
            bw.flush();  // 确保所有数据都被写入
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例说明:

  • 创建 OutputStream:这里使用标准输出流 System.out 作为 OutputStream

  • 创建 OutputStreamWriter:使用 outputStream 创建一个 OutputStreamWriter,并指定字符集为 "UTF-8"

  • 创建 BufferedWriter:使用 OutputStreamWriter 创建一个 BufferedWriter,以便高效地写入数据。

  • 写入数据:通过 BufferedWriterwrite() 方法写入字符串 content

  • 换行:使用 newLine() 方法写入换行符。

  • 刷新:使用 flush() 方法确保所有数据都被写入。

使用转换流进行文件读写

假设有一个文本文件 input.txt,需要读取该文件的内容,并将内容写入另一个文件 output.txt

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;

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

        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(inputFilePath), "UTF-8");
             BufferedReader br = new BufferedReader(isr);
             OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(outputFilePath), "UTF-8");
             BufferedWriter bw = new BufferedWriter(osw)) {

            String line;
            while ((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例说明:

  • 创建 InputStreamReader:使用 FileInputStream 创建一个 InputStreamReader,并指定字符集为 "UTF-8"

  • 创建 BufferedReader:使用 InputStreamReader 创建一个 BufferedReader,以便逐行读取数据。

  • 创建 OutputStreamWriter:使用 FileOutputStream 创建一个 OutputStreamWriter,并指定字符集为 "UTF-8"

  • 创建 BufferedWriter:使用 OutputStreamWriter 创建一个 BufferedWriter,以便高效地写入数据。

  • 读取和写入数据:通过 BufferedReaderreadLine() 方法逐行读取数据,并通过 BufferedWriterwrite() 方法写入数据。

  • 换行:使用 newLine() 方法写入换行符。

  • 刷新:使用 flush() 方法确保所有数据都被写入。

扫描流

扫描流 Scannerjava.util.Scanner 中的一个类,它可以用来从标准输入、文件、字符串等多种来源中获取输入。使用 Scanner 类能够方便、快速地从输入流中读取数据。

Scanner 类还提供了许多其他方法,例如 nextInt()nextDouble() 等,用于读取不同数据类型的输入。

构造方法

Java 中 java.util.Scanner 类提供了多个构造方法,用于创建不同类型的 Scanner 对象。

  1. Scanner(File source):创建一个从指定文件中读取数据的 Scanner 对象。
File file = new File("input.txt");
Scanner scanner = new Scanner(file);
  1. Scanner(InputStream source):创建一个从指定输入流中读取数据的 Scanner 对象。
InputStream inputStream = System.in;
Scanner scanner = new Scanner(inputStream);
  1. Scanner(String source):创建一个从指定字符串中读取数据的 Scanner 对象。
String text = "Hello, world!";
Scanner scanner = new Scanner(text);
  1. Scanner(File source, String charsetName):创建一个从指定文件使用指定字符集编码中读取数据的 Scanner 对象。
File file = new File("input.txt");
Scanner scanner = new Scanner(file, "UTF-8");
  1. Scanner(InputStream source, String charsetName):创建一个从指定输入流使用指定字符集编码中读取数据的 Scanner 对象。
InputStream inputStream = System.in;
Scanner scanner = new Scanner(inputStream, "UTF-8");

上述构造方法中的 source 参数均为输入源,charsetName 参数用于指定字符集编码(可选参数)。

System.in

System.in 是 Java 标准库中的一个静态字段,它是 java.io.InputStream 类型的对象,用于表示标准输入流。在控制台应用程序中,System.in 表示标准输入(键盘输入)。

可以通过创建 Scanner 对象,并将 System.in 作为参数传递给 Scanner 构造方法,使用 Scanner 对象读取从键盘输入的数据。

Scanner scan = new Scanner(System.in);
String string = scan.nextline();
int age = scan.nextInt();
scan.close();

打印流

System.out 实际是用于获取一个 PrintStream 对象,print方法实际调用的是 PrintStream 对象的 write 方法。

PrintStream 属于字节打印流,与之对应的孪生兄弟是 PrintWriter (字符打印流)。PrintStreamOutputStream 的子类,PrintWriterWriter 的子类。

打印流具有以下几个特点:

  • 可以自动进行数据类型转换:打印流可以将各种数据类型转换为字符串,并输出到指定的输出流中。

  • 可以自动进行换行操作:打印流可以在输出字符串的末尾自动添加换行符,方便输出多个字符串时的格式控制。

  • 可以输出到控制台或者文件中:打印流可以将数据输出到控制台或者文件中,方便调试和日志记录(生产环境下更推荐使用 Logback、ELK 等)。

PrintStream 类的常用方法包括:

  • print():输出一个对象的字符串表示形式。

  • println():输出一个对象的字符串表示形式,并在末尾添加一个换行符。

  • printf():使用指定的格式字符串和参数输出格式化的字符串。

Java 的常用转换说明符

转换符说明
%d or %i输出一个十进制整数。
%s输出一个字符串。
%x or %X输出一个十六进制整数,%x 输出小写字母,%X 输出大写字母。
%f or %F输出一个浮点数。
%e or %E输出一个科学计数法表示的浮点数,%e 输出小写字母 e,%E 输出大写字母 E。
%g or %G输出一个浮点数,自动选择 %f 或 %e/%E 格式输出。
%c输出一个字符。
%b输出一个布尔值。
%h输出一个哈希码(16进制)。
%n换行符。

Java printf 支持的修饰符

Java 的 printf 方法还支持一些修饰符,用于指定输出的宽度、精度、对齐方式等(类似C、C++)。

  • 宽度修饰符:用数字指定输出的最小宽度,如果输出的数据不足指定宽度,则在左侧或右侧填充空格或零。

  • 精度修饰符:用点号(.)和数字指定浮点数或字符串的精度,对于浮点数,指定小数点后的位数,对于字符串,指定输出的字符数。

  • 对齐修饰符:用减号(-)或零号(0)指定输出的对齐方式,减号表示左对齐,零号表示右对齐并填充零。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值