← 返回首页
🌊

Java IO流深入:缓冲流、转换流与数据流

📂 java ⏱ 4 min 789 words

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. 最佳实践

  1. 使用缓冲流:提高IO性能
  2. 指定编码:使用InputStreamReader/OutputStreamWriter指定编码
  3. 使用try-with-resources:自动关闭资源
  4. 选择合适的流:根据需求选择合适的流类型
  5. 注意异常处理:妥善处理IOException

总结

Java IO流提供了丰富的流类型来处理不同的IO需求。掌握缓冲流、转换流和数据流的使用,可以高效地处理文件读写、数据序列化等任务。