一、标准输入输出(控制台)
1. 标准输出System.out
System.out.print()/println()/printf()最常用的控制台输出。
java
System.out.println("普通输出"); System.out.printf("格式化输出:%d + %d = %d%n", 3, 5, 3 + 5);2. 标准输入System.in
System.in是字节流(InputStream),通常用Scanner或BufferedReader包装。
方式一:Scanner(最常用)
java
import java.util.Scanner; Scanner sc = new Scanner(System.in); System.out.print("请输入姓名:"); String name = sc.nextLine(); System.out.print("请输入年龄:"); int age = sc.nextInt(); System.out.println(name + " 今年 " + age + " 岁"); sc.close();方式二:BufferedReader(效率高,需处理异常)
java
import java.io.BufferedReader; import java.io.InputStreamReader; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("请输入内容:"); String line = br.readLine(); System.out.println("你输入了:" + line); br.close();二、文件 I/O 基础
Java I/O 分为字节流和字符流,顶层抽象类:
字节流:
InputStream/OutputStream字符流:
Reader/Writer
1. 字节流读写文件(适合图片、视频等二进制文件)
文件输入流(FileInputStream)
java
import java.io.FileInputStream; import java.io.IOException; try (FileInputStream fis = new FileInputStream("test.txt")) { int b; while ((b = fis.read()) != -1) { System.out.print((char) b); } } catch (IOException e) { e.printStackTrace(); }文件输出流(FileOutputStream)
java
import java.io.FileOutputStream; import java.io.IOException; try (FileOutputStream fos = new FileOutputStream("output.txt")) { String data = "Hello, Java I/O!"; fos.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); }拷贝文件(字节流一次读取一个字节数组)
java
try (FileInputStream fis = new FileInputStream("src.jpg"); FileOutputStream fos = new FileOutputStream("dst.jpg")) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); }2. 字符流读写文件(适合文本文件)
FileReader / FileWriter
java
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; // 写文本文件 try (FileWriter fw = new FileWriter("note.txt")) { fw.write("第一行内容\n"); fw.write("第二行内容"); } catch (IOException e) { e.printStackTrace(); } // 读文本文件 try (FileReader fr = new FileReader("note.txt")) { int ch; while ((ch = fr.read()) != -1) { System.out.print((char) ch); } } catch (IOException e) { e.printStackTrace(); }3. 缓冲流(提高性能)
BufferedInputStream/BufferedOutputStream(字节缓冲)BufferedReader/BufferedWriter(字符缓冲,支持按行读写)
使用 BufferedReader 按行读取
java
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); }使用 BufferedWriter 按行写入
java
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; try (BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"))) { bw.write("第一行"); bw.newLine(); bw.write("第二行"); } catch (IOException e) { e.printStackTrace(); }三、转换流(字节 ↔ 字符)
InputStreamReader:字节→字符OutputStreamWriter:字符→字节
通常用于指定编码(如 UTF-8, GBK)。
java
import java.io.*; // 以 UTF-8 编码读取文件 try (BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream("utf8.txt"), "UTF-8"))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } // 以 GBK 编码写入文件 try (BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(new FileOutputStream("gbk.txt"), "GBK"))) { bw.write("中文内容"); } catch (IOException e) { e.printStackTrace(); }四、NIO(New I/O,Java 1.4+)
NIO 提供更高效的非阻塞 I/O,核心:Channel+Buffer+Selector。
简单示例:使用 FileChannel 拷贝文件
java
import java.io.*; import java.nio.channels.FileChannel; try (FileChannel src = new FileInputStream("src.txt").getChannel(); FileChannel dest = new FileOutputStream("dest.txt").getChannel()) { dest.transferFrom(src, 0, src.size()); } catch (IOException e) { e.printStackTrace(); }使用 Files 工具类(Java 7+,最简洁)
java
import java.nio.file.*; // 一次性读取所有行 List<String> lines = Files.readAllLines(Paths.get("data.txt"), StandardCharsets.UTF_8); lines.forEach(System.out::println); // 一次性写入 List<String> content = Arrays.asList("行1", "行2", "行3"); Files.write(Paths.get("out.txt"), content, StandardCharsets.UTF_8); // 复制文件 Files.copy(Paths.get("a.txt"), Paths.get("b.txt"), StandardCopyOption.REPLACE_EXISTING);五、常见问题与最佳实践
| 问题 | 建议 |
|---|---|
| 中文乱码 | 使用InputStreamReader/OutputStreamWriter指定编码,如UTF-8 |
| 忘记关闭流 | 使用try-with-resources(Java 7+)自动关闭 |
| 效率低 | 使用缓冲流(BufferedReader/BufferedWriter) |
| 大文件读取 | 使用BufferedReader按行读,或 NIO 的Files.lines() |
| 需要随机访问 | 使用RandomAccessFile或 NIO 的FileChannel |
六、完整综合示例(含异常处理)
java
import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.*; public class IODemo { public static void main(String[] args) { // 写入 try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("demo.txt"), StandardCharsets.UTF_8)) { bw.write("Hello, 你好"); bw.newLine(); bw.write("第二行"); } catch (IOException e) { e.printStackTrace(); } // 读取 try (BufferedReader br = Files.newBufferedReader(Paths.get("demo.txt"), StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }