文章目录
- [一、Java I/O 的核心概念](#一、Java I/O 的核心概念)
- 二、控制台输入输出(最基础)
-
- [2.1. 控制台输出(Output)](#2.1. 控制台输出(Output))
- [2.2. 控制台输入(Input)](#2.2. 控制台输入(Input))
- 三、文件输入输出(基础版)
-
- [3.1. 向文件写入内容(输出)](#3.1. 向文件写入内容(输出))
- [3.2. 从文件读取内容(输入)](#3.2. 从文件读取内容(输入))
- [四、简化版文件 I/O(Java 7+)](#四、简化版文件 I/O(Java 7+))
一、Java I/O 的核心概念
Java 的 I/O(Input/Output)本质是程序与外部设备(如控制台、文件、网络)之间的数据传输,核心分为两类:
- 输入(Input):从外部设备读取数据到程序中(比如从控制台读用户输入、从文件读内容)。
- 输出(Output):将程序中的数据写入外部设备(比如向控制台打印内容、向文件写内容)。
Java 提供了两套核心的 I/O 体系:
- 传统 I/O(java.io 包):基于流(Stream),是基础且最常用的方式,适合新手入门。
- NIO(java.nio 包):非阻塞 I/O,适合高并发场景,新手先掌握传统 I/O 即可。
下面重点讲解新手最常用的控制台 I/O和文件 I/O。
二、控制台输入输出(最基础)
控制台是程序与用户交互的最直接方式,先看最简单的输出,再讲输入。
2.1. 控制台输出(Output)
最常用的是System.out.println(),核心用法如下:
java
public class ConsoleOutput {
public static void main(String[] args) {
// 1. 输出内容并换行
System.out.println("Hello World!");
// 2. 输出内容不换行
System.out.print("你好,");
System.out.print("Java!");
// 3. 格式化输出(类似C语言的printf)
String name = "小明";
int age = 20;
System.out.printf("姓名:%s,年龄:%d%n", name, age);
// %s:字符串占位符,%d:整数占位符,%n:换行(跨平台)
}
}
关于占位符详情见详解printf 和 scanf
输出结果:
html
Hello World!
你好,Java!姓名:小明,年龄:20
2.2. 控制台输入(Input)
Java 5 + 推荐使用Scanner类(位于java.util包),简单易用,适合新手:
java
import java.util.Scanner; // 必须导入Scanner类
public class ConsoleInput {
public static void main(String[] args) {
// 1. 创建Scanner对象,关联控制台输入(System.in)
Scanner scanner = new Scanner(System.in);
// 2. 读取不同类型的输入
System.out.print("请输入你的姓名:");
String name = scanner.nextLine(); // 读取一行字符串(包含空格)
System.out.print("请输入你的年龄:");
int age = scanner.nextInt(); // 读取整数
System.out.print("请输入你的身高(米):");
double height = scanner.nextDouble(); // 读取小数
// 3. 输出验证
System.out.println("你的信息:");
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("身高:" + height + "米");
// 4. 关闭Scanner(释放资源)
scanner.close();
}
}
输入示例:
html
请输入你的姓名:张三
请输入你的年龄:25
请输入你的身高(米):1.75
输出结果:
html
你的信息:
姓名:张三
年龄:25
身高:1.75米
读取字符串的方法:
java
//读入字符串
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine(); //读入一整行,如abc def读出来也是abc def。
System.out.println(str);
String str2 = scanner.next(); //遇到空格结束,如abc def读出来是abc
System.out.println(str2);
}
注意事项:
- nextInt() / nextDouble() 读取后,光标会停留在换行符处,若后续用nextLine()读取字符串,需先调用scanner.nextLine()吸收换行符。
java
// 这个问题是由于Scanner类的输入缓冲机制导致的。当使用nextInt()读取年龄后,用户按下的回车键(\n)会留在输入缓冲区中,
// 随后nextLine()会立即读取到这个换行符并返回空字符串。
public static void main3(String[] args) {
Scanner scanner = new Scanner(System.in);
//这个如果放在前面,姓名就读不到:因为你输入年龄后会进行回车一下,此时后面就会读走回车,此时多加一个nextLine读走回车
System.out.println("请输入你的年龄");
int age = scanner.nextInt();
System.out.println(age);
scanner.nextLine(); //读取回车
System.out.println("请输入你的姓名");
String name = scanner.nextLine();
System.out.println(name);
}
理解:工作原理
- nextInt()的工作原理
- 只会读取到数字字符,遇到非数字字符(包括空格、回车)就会停止
- 不会读取和小号数字后面的换行符\n
- 所以代码执行流程
- 第一个nextInt读取到年龄数字后,回车符\n留在缓冲区
- 第二个nextInt会跳过前导空白字符(包括上次留下的\n),然后读取体重数字
java
public static void main5(String[] args) {
Scanner scanner = new Scanner(System.in);
//如果输入 空格空格123,会直接跳过空格找到数字并进行输入;如果输入123 456,则会进行输入123
System.out.println("请输入你的年龄");
int age = scanner.nextInt();
System.out.println(age);
//上面如果输入123 456,则会自动读取在缓冲区的数据456,所以得到456
System.out.println("请输入你的体重");
double weight = scanner.nextDouble();
System.out.println(weight);
}
- 若输入类型不匹配(比如输入字符串却用nextInt()读取),会抛出InputMismatchException,新手可先暂时忽略异常处理,关于学习 try-catch 捕获异常可以看Java中的异常。
java
public class MyInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//读取一个整数
int age = scanner.nextInt();
System.out.println("年龄是:" + age);
//读取一行字符串
String name = scanner.nextLine();
System.out.println("姓名是:" + name);
}
}
输入示例:
html
Hello world!
输出结果:
html
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at MyIO.MyInput.main(MyInput.java:10)
三、文件输入输出(基础版)
除了控制台,文件 I/O 是最常用的场景,这里用FileReader/FileWriter(字符流,适合文本文件)举例:
3.1. 向文件写入内容(输出)
java
import java.io.FileWriter;
import java.io.IOException;
public class FileOutput {
public static void main(String[] args) {
// 声明FileWriter对象
FileWriter writer = null;
try {
// 1. 创建FileWriter:参数1=文件路径,参数2=true表示追加内容(默认false覆盖)
writer = new FileWriter("test.txt", true);
// 2. 写入内容
/* while(scanner.hasNextLine()) {
String str = scanner.nextLine();
writer.write(str + "\n");
System.out.println("内容写入成功!");
}*/
writer.write("Java I/O 学习\n"); // 写入字符串,\n换行
writer.write("文件输出示例\n");
System.out.println("内容写入成功!");
} catch (IOException e) {
// 捕获IO异常(比如文件路径不存在、权限不足)
e.printStackTrace();
} finally {
// 3. 关闭流(必须在finally中执行,确保资源释放)
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行后,项目根目录会生成test.txt文件,内容为:
html
Java I/O 学习
文件输出示例
3.2. 从文件读取内容(输入)
java
import java.io.FileReader;
import java.io.IOException;
public class FileInput {
public static void main(String[] args) {
FileReader reader = null;
try {
// 1. 创建FileReader,关联要读取的文件
reader = new FileReader("test.txt");
// 2. 读取内容:read()返回单个字符的ASCII码,-1表示读取完毕
int ch;
System.out.println("文件内容:");
while ((ch = reader.read()) != -1) {
System.out.print((char) ch); // 转换为字符输出
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3. 关闭流
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四、简化版文件 I/O(Java 7+)
Java 7 引入了try-with-resources语法,无需手动关闭流,代码更简洁:
java
import java.io.FileWriter;
import java.io.IOException;
public class AutoCloseIO {
public static void main(String[] args) {
// try括号内的流会自动关闭
try (FileWriter writer = new FileWriter("test2.txt")) {
writer.write("自动关闭流的示例\n");
System.out.println("写入成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}