Bootstrap

【新手向】从零开始学习Java(Day14)流、文件和IO

每天二十分钟,成就Java大神,点点关注不迷路!

今天是第十四天,给坚持到这里的小伙伴点个赞!

那些杀不死我的,必使我更强大,共勉!


目录

读取控制台的输入

BufferedReader 类

read()读取一个字符

例子

readLine()读取字符串

例子

Scanner 类

控制台输出

文件读写

java.io

读取文件

写入文件

java.nio(了解)

读取文件

写入文件

下节预告


Java 中的流(Stream)、文件(File)和 输入输出(IO)是处理数据读取和写入的基础设施,它们允许程序与外部数据(如文件、网络、系统输入等)进行交互。

java.io 包是 Java 标准库中的一个核心包,是处理文件操作、流操作以及低级别 IO 操作的基础包。它提供了用于系统输入和输出的类,包含了处理数据流(字节流和字符流)、文件读写、序列化以及数据格式化的工具。

一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据


读取控制台的输入

Java 的控制台输入由 System.in 完成。

BufferedReader

为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。

下面是创建 BufferedReader 的基本语法:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

BufferedReader 对象创建后,我们便可以使用他的 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。

read()读取一个字符

每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。

int read( ) throws IOException
例子

下面的程序示范了用 read() 方法从控制台不断读取字符直到用户输入 q:

//使用 BufferedReader 在控制台读取字符
import java.io.*;
 
public class BRRead {
    public static void main(String[] args) throws IOException {
        char c;
        // 使用 System.in 创建 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输入字符, 按下 'q' 键退出。");
        // 读取字符
        do {
            c = (char) br.read();
            System.out.println(c);
        } while (c != 'q');
    }
}

readLine()读取字符串

从标准输入读取一个字符串需要使用 BufferedReader 的 readLine() 方法,语法如下:

String readLine( ) throws IOException
例子
//使用 BufferedReader 在控制台读取字符
import java.io.*;

public class BRReadLines {
    public static void main(String[] args) throws IOException {
        // 使用 System.in 创建 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        System.out.println("Enter lines of text.");
        System.out.println("Enter 'end' to quit.");
        do {
            str = br.readLine();
            System.out.println(str);
        } while (!str.equals("end"));
    }
}

Scanner 类

JDK 5 后的版本更多使用Scanner 类来获取控制台的输入,Scanner 类提供了多种方法来读取用户输入的不同类型数据,如整数、浮点数、字符串等。

导入Scanner 类,创建Scanner 对象

import java.util.Scanner;
Scanner scanner = new Scanner(System.in);

读取不同类型的输入

System.out.print("请输入一个字符串: ");
String str = scanner.nextLine();
System.out.println("你输入的字符串是: " + str);

System.out.print("请输入一个整数: ");
int num = scanner.nextInt();
System.out.println("你输入的整数是: " + num);

System.out.print("请输入一个浮点数: ");
double decimal = scanner.nextDouble();
System.out.println("你输入的浮点数是: " + decimal);

System.out.print("请输入一个布尔值(true/false): ");
boolean bool = scanner.nextBoolean();
System.out.println("你输入的布尔值是: " + bool);

关闭Scanner 对象

在使用完Scanner 对象后,最好关闭它以释放资源

scanner.close();

注意:

  • nextLine() 方法会读取整行输入,包括空格,直到遇到换行符为止。而next() 方法只会读取下一个单词(以空格为分隔符)
  • 在使用nextInt()、nextDouble() 等方法时,如果用户输入的数据类型不匹配,会抛出InputMismatchException 异常。因此,在实际应用中,通常需要添加异常处理机制。
import java.util.InputMismatchException;
import java.util.Scanner;

public class wrongInput {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        try {
            System.out.print("请输入一个整数: ");
            int num = scanner.nextInt();
            System.out.println("你输入的整数是: " + num);
        } catch (InputMismatchException e) {
            System.out.println("输入的不是一个有效的整数!");
        } finally {
            scanner.close();
        }
    }
}

控制台输出

控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用

PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。但write() 方法不经常使用,因为 print() 和 println() 方法用起来更为方便。

下面是所有控制台输出方法:

方法描述
System.out.print()输出内容到控制台,不换行

System.out.println()

输出内容到控制台,并在末尾自动换行
System.out.printf()

格式化输出,类似于C语言中的 printf 函数。

\可以使用格式化字符串来控制输出的格式。

System.out.format()与 printf 类似,也是格式化输出
System.out.append()将字符或字符串追加到输出流中。
System.out.write()字节写入输出流。通常用于低级操作,不常用。

System.err.print()和

System.err.println()

错误信息输出到控制台(通常是红色字体)

文件读写

在Java中,文件读写主要通过以下两种方式实现:

  1. 传统IO(java.io包):基于流(Stream)的模型,适合处理简单的文件操作。

  2. NIO(java.nio包):基于通道(Channel)和缓冲区(Buffer)的模型,适合高效处理大文件或并发操作。

java.io

读取文件

1.使用 FileReader 和 BufferedReader

BufferedReader可以逐行读取文件内容,适合处理文本文件。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample {
    public static void main(String[] args) {
        String filePath = "example.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();
        }
    }
}

2.使用 FileInputStream 和 Scanner

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;

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

        try (FileInputStream fis = new FileInputStream(filePath);
             Scanner scanner = new Scanner(fis)) {
            while (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine()); // 逐行读取并输出
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

写入文件

1.使用 FileWriter和 BufferedWriter

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class WriteFileExample {
    public static void main(String[] args) {
        String filePath = "output.txt"; // 文件路径
        String content = "Hello, World!\nThis is a new line.";

        try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
            bw.write(content); // 写入内容
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.使用 FileOutputStream

import java.io.FileOutputStream;
import java.io.IOException;

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

        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(content.getBytes()); // 将字符串转换为字节数组并写入
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

java.nio(了解)

读取文件

1.使用Files.readAllLines()

Files.readAllLines() 可以一次性读取文件的所有行,适合小文件。

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.io.IOException;

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

        try {
            List<String> lines = Files.readAllLines(Paths.get(filePath)); // 读取所有行
            for (String line : lines) {
                System.out.println(line); // 逐行输出
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.使用Files.lines()

Java 8后引入Files.lines() ,它返回一个流(Stream),适合处理大文件。

import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.stream.Stream;

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

        try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
            lines.forEach(System.out::println); // 使用流逐行处理
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

写入文件

1.使用Files.write()

Files.write()可以一次性写入多行内容

import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class WriteFileNIOExample {
    public static void main(String[] args) {
        String filePath = "output.txt"; // 文件路径
        List<String> lines = Arrays.asList("Line 1", "Line 2", "Line 3");

        try {
            Files.write(Paths.get(filePath), lines); // 写入多行内容
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.使用Files.BufferedWriter()

import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.BufferedWriter;
import java.io.IOException;

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

        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath))) {
            writer.write("Hello, World!\n");
            writer.write("This is a new line.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

下节预告

上面举例子时,使用try...catch的形式,这是java中捕获异常的方式。下节开始,笔者将详细展开介绍 Java 中的异常处理,看到这里的小伙伴可以投票打卡(投票有效期为7天),有疑惑可私信或评论区提出,and不妨动动发财的手点个赞吧,明天见!