Java IO流深入:缓冲流、转换流与数据流
Java IO流深入:缓冲流、转换流与数据流
概述
Java IO流提供了多种流类型来处理不同的IO需求。本教程深入介绍缓冲流、转换流和数据流的使用。
1. 缓冲流
BufferedInputStream和BufferedOutputStream
import java.io.*;
public class BufferedStreamExample {
public static void main(String[] args) {
// 写入文件
try (BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("buffered.txt"))) {
String content = "Hello, Buffered Stream!";
bos.write(content.getBytes());
System.out.println("缓冲写入完成");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 读取文件
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("buffered.txt"))) {
byte[] buffer = new byte[1024];
int bytesRead;
StringBuilder content = new StringBuilder();
while ((bytesRead = bis.read(buffer)) != -1) {
content.append(new String(buffer, 0, bytesRead));
}
System.out.println("缓冲读取: " + content.toString());
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
}
}
BufferedReader和BufferedWriter
import java.io.*;
public class CharBufferedExample {
public static void main(String[] args) {
// 写入文件
try (BufferedWriter bw = new BufferedWriter(new FileWriter("charbuffered.txt"))) {
bw.write("第一行");
bw.newLine();
bw.write("第二行");
bw.newLine();
bw.write("第三行");
System.out.println("字符缓冲写入完成");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 读取文件
try (BufferedReader br = new BufferedReader(new FileReader("charbuffered.txt"))) {
String line;
int lineNumber = 1;
while ((line = br.readLine()) != null) {
System.out.println(lineNumber + ": " + line);
lineNumber++;
}
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
// 使用BufferedReader逐字符读取
try (BufferedReader br = new BufferedReader(new FileReader("charbuffered.txt"))) {
int data;
while ((data = br.read()) != -1) {
System.out.print((char) data);
}
System.out.println();
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
}
}
2. 转换流
InputStreamReader和OutputStreamWriter
import java.io.*;
import java.nio.charset.*;
public class转换流Example {
public static void main(String[] args) {
// 指定编码写入
try (OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("utf8.txt"), StandardCharsets.UTF_8)) {
osw.write("你好,世界!");
osw.write("\n");
osw.write("Hello, World!");
System.out.println("UTF-8写入完成");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 指定编码读取
try (InputStreamReader isr = new InputStreamReader(
new FileInputStream("utf8.txt"), StandardCharsets.UTF_8)) {
char[] buffer = new char[1024];
int charsRead;
StringBuilder content = new StringBuilder();
while ((charsRead = isr.read(buffer)) != -1) {
content.append(buffer, 0, charsRead);
}
System.out.println("UTF-8读取: " + content.toString());
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
// 字节流转换为字符流
try (BufferedReader br = new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8))) {
System.out.print("请输入: ");
String input = br.readLine();
System.out.println("你输入了: " + input);
} catch (IOException e) {
System.out.println("输入异常: " + e.getMessage());
}
}
}
3. 数据流
DataInputStream和DataOutputStream
import java.io.*;
public class DataStreamExample {
public static void main(String[] args) {
// 写入基本数据类型
try (DataOutputStream dos = new DataOutputStream(
new FileOutputStream("data.bin"))) {
dos.writeInt(123);
dos.writeDouble(3.14);
dos.writeBoolean(true);
dos.writeUTF("Hello");
dos.writeChar('A');
dos.writeLong(1000000L);
System.out.println("数据写入完成");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 读取基本数据类型
try (DataInputStream dis = new DataInputStream(
new FileInputStream("data.bin"))) {
int i = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
String s = dis.readUTF();
char c = dis.readChar();
long l = dis.readLong();
System.out.println("int: " + i);
System.out.println("double: " + d);
System.out.println("boolean: " + b);
System.out.println("String: " + s);
System.out.println("char: " + c);
System.out.println("long: " + l);
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
}
}
4. 推回输入流
PushbackInputStream
import java.io.*;
public class PushbackExample {
public static void main(String[] args) {
try {
String data = "Hello 123 World 456";
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes());
PushbackInputStream pis = new PushbackInputStream(bais);
int c;
StringBuilder number = new StringBuilder();
while ((c = pis.read()) != -1) {
if (Character.isDigit((char) c)) {
number.append((char) c);
} else {
if (number.length() > 0) {
System.out.println("找到数字: " + number.toString());
number.setLength(0);
}
pis.unread(c); // 推回非数字字符
}
}
if (number.length() > 0) {
System.out.println("找到数字: " + number.toString());
}
} catch (IOException e) {
System.out.println("异常: " + e.getMessage());
}
}
}
5. 实际应用示例
文件复制工具
import java.io.*;
public class FileCopyUtils {
public static void copyFile(String source, String dest) throws IOException {
File sourceFile = new File(source);
File destFile = new File(dest);
// 使用缓冲流复制
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile))) {
byte[] buffer = new byte[8192];
int bytesRead;
long totalBytes = 0;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
System.out.println("复制完成: " + totalBytes + " 字节");
}
}
public static void main(String[] args) {
try {
copyFile("source.txt", "dest.txt");
} catch (IOException e) {
System.out.println("复制异常: " + e.getMessage());
}
}
}
日志文件分析器
import java.io.*;
import java.util.*;
public class LogAnalyzer {
public static Map<String, Integer> analyzeLog(String logFile) throws IOException {
Map<String, Integer> levelCount = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(logFile))) {
String line;
while ((line = br.readLine()) != null) {
String level = extractLevel(line);
if (level != null) {
levelCount.merge(level, 1, Integer::sum);
}
}
}
return levelCount;
}
private static String extractLevel(String line) {
if (line.contains("[ERROR]")) return "ERROR";
if (line.contains("[WARN]")) return "WARN";
if (line.contains("[INFO]")) return "INFO";
if (line.contains("[DEBUG]")) return "DEBUG";
return null;
}
public static void main(String[] args) {
try {
Map<String, Integer> stats = analyzeLog("app.log");
System.out.println("日志统计:");
stats.forEach((level, count) ->
System.out.println(level + ": " + count));
} catch (IOException e) {
System.out.println("分析异常: " + e.getMessage());
}
}
}
6. 最佳实践
- 使用缓冲流:提高IO性能
- 指定编码:使用InputStreamReader/OutputStreamWriter指定编码
- 使用try-with-resources:自动关闭资源
- 选择合适的流:根据需求选择合适的流类型
- 注意异常处理:妥善处理IOException
总结
Java IO流提供了丰富的流类型来处理不同的IO需求。掌握缓冲流、转换流和数据流的使用,可以高效地处理文件读写、数据序列化等任务。