# Java IO编程

Java IO(输入/输出)提供了一系列用于处理输入和输出的类和接口。

# 文件操作

# 基本文件操作

// 创建文件对象
File file = new File("example.txt");

// 文件基本信息
boolean exists = file.exists();
boolean isDirectory = file.isDirectory();
long length = file.length();
String path = file.getAbsolutePath();

// 创建和删除
boolean created = file.createNewFile();
boolean deleted = file.delete();

# 文件读写

// 写入文件
try (FileWriter writer = new FileWriter("output.txt")) {
    writer.write("Hello, Java IO!");
} catch (IOException e) {
    e.printStackTrace();
}

// 读取文件
try (FileReader reader = new FileReader("input.txt")) {
    char[] buffer = new char[1024];
    int length;
    while ((length = reader.read(buffer)) != -1) {
        System.out.println(new String(buffer, 0, length));
    }
} catch (IOException e) {
    e.printStackTrace();
}

# 流操作

# 字节流

// 文件输出流
try (FileOutputStream fos = new FileOutputStream("data.bin")) {
    byte[] data = {65, 66, 67, 68}; // ABCD
    fos.write(data);
} catch (IOException e) {
    e.printStackTrace();
}

// 文件输入流
try (FileInputStream fis = new FileInputStream("data.bin")) {
    int data;
    while ((data = fis.read()) != -1) {
        System.out.print((char) data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

# 字符流

// 缓冲字符输出流
try (BufferedWriter writer = new BufferedWriter(new FileWriter("text.txt"))) {
    writer.write("第一行");
    writer.newLine();
    writer.write("第二行");
} catch (IOException e) {
    e.printStackTrace();
}

// 缓冲字符输入流
try (BufferedReader reader = new BufferedReader(new FileReader("text.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

# 高级IO操作

# 序列化

// 可序列化的类
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 对象序列化
try (ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("person.dat"))) {
    Person person = new Person("张三", 25);
    oos.writeObject(person);
} catch (IOException e) {
    e.printStackTrace();
}

// 对象反序列化
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("person.dat"))) {
    Person person = (Person) ois.readObject();
    System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

# NIO(New IO)

// 使用Path
Path path = Paths.get("example.txt");
Files.createFile(path);

// 读取文件所有行
List<String> lines = Files.readAllLines(path);

// 写入文件
Files.write(path, Arrays.asList("行1", "行2"), StandardCharsets.UTF_8);

// 使用Channel
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int bytesRead = channel.read(buffer);
    buffer.flip();
    // 处理数据
} catch (IOException e) {
    e.printStackTrace();
}

# 实践案例

# 文件复制工具

public class FileCopyUtil {
    public static void copyFile(String source, String target) throws IOException {
        try (FileInputStream fis = new FileInputStream(source);
             FileOutputStream fos = new FileOutputStream(target)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        }
    }

    public static void copyFileNIO(String source, String target) throws IOException {
        Path sourcePath = Paths.get(source);
        Path targetPath = Paths.get(target);
        Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
    }
}

# 练习

  1. 实现一个简单的文本编辑器,支持文件的读写操作
  2. 创建一个文件备份工具,定期备份指定目录下的文件
  3. 开发一个日志记录系统,将日志信息写入文件

# 高级特性

以下是一些高级IO特性:

  1. 多线程IO
// 多线程文件读写示例
public class ConcurrentFileIO {
    private static final String FILE_PATH = "shared_file.txt";
    private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    // 线程安全的写操作
    public static void writeToFile(String content) {
        lock.writeLock().lock();
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH, true))) {
            writer.write(content);
            writer.newLine();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }

    // 线程安全的读操作
    public static List<String> readFromFile() {
        lock.readLock().lock();
        List<String> lines = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
            String line;
            while ((line = reader.readLine()) != null) {
                lines.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
        return lines;
    }
}
  1. 异步IO
// 异步文件操作示例
public class AsyncFileIO {
    public static void main(String[] args) throws Exception {
        Path file = Paths.get("async_example.txt");
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(
            file, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE
        );

        // 异步写入
        ByteBuffer writeBuffer = ByteBuffer.wrap("Hello Async IO!\n".getBytes());
        Future<Integer> writeResult = fileChannel.write(writeBuffer, 0);
        
        // 等待写入完成
        writeResult.get();

        // 异步读取
        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
        fileChannel.read(readBuffer, 0, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                attachment.flip();
                System.out.println(new String(attachment.array(), 0, result));
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });

        fileChannel.close();
    }
}
  1. 文件监控
// 文件监控示例
public class FileWatcherService {
    private final WatchService watchService;
    private final Map<WatchKey, Path> keys;

    public FileWatcherService(Path dir) throws IOException {
        this.watchService = FileSystems.getDefault().newWatchService();
        this.keys = new HashMap<>();
        registerDirectory(dir);
    }

    private void registerDirectory(Path dir) throws IOException {
        WatchKey key = dir.register(watchService,
            StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_DELETE,
            StandardWatchEventKinds.ENTRY_MODIFY);
        keys.put(key, dir);
    }

    public void startMonitoring() {
        try {
            while (true) {
                WatchKey key = watchService.take();
                Path dir = keys.get(key);
                if (dir == null) continue;

                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();
                    Path name = (Path) event.context();
                    Path child = dir.resolve(name);

                    System.out.printf("%s: %s\n", kind.name(), child);

                    if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                        if (Files.isDirectory(child)) {
                            registerDirectory(child);
                        }
                    }
                }

                if (!key.reset()) {
                    keys.remove(key);
                    if (keys.isEmpty()) {
                        break;
                    }
                }
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        Path dir = Paths.get(".");
        FileWatcherService watcher = new FileWatcherService(dir);
        watcher.startMonitoring();
    }
}

这些高级IO特性能够帮助你构建更强大的Java应用:

  • 多线程IO适用于需要并发处理大量文件操作的场景
  • 异步IO可以提高IO密集型应用的性能
  • 文件监控功能可用于构建自动化工具和实时同步系统