ZetCode

Java PipedWriter 类

最后修改时间:2025 年 4 月 16 日

java.io.PipedWriter 类是一个字符流,可以连接到 PipedReader 以创建通信管道。它以线程安全的方式将字符写入连接的 PipedReader

PipedWriter 通常用于线程之间的通信。管道维护一个内部缓冲区,默认大小为 1024 个字符。管道的两端必须连接才能正常运行。

PipedWriter 类概述

PipedWriter 继承自 Writer 并提供管道输出操作。主要方法包括写入字符、连接到读取器、刷新和关闭。如果管道中断,该类将抛出 IOException

public class PipedWriter extends Writer {
    public PipedWriter();
    public PipedWriter(PipedReader snk);
    public synchronized void connect(PipedReader snk);
    public void write(int c);
    public void write(char[] cbuf, int off, int len);
    public synchronized void flush();
    public void close();
}

上面的代码显示了 PipedWriter 提供的关键方法。这些方法允许将字符写入连接的 PipedReader。连接可以在创建时或稍后建立。

创建 PipedWriter

PipedWriter 可以创建,无论是否连接了读取器。如果创建时未连接,则必须在使用前连接。每个 PipedWriter 实例只能建立一次连接。

Main.java
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            // Create unconnected PipedWriter
            PipedWriter writer1 = new PipedWriter();
            
            // Create connected PipedWriter
            PipedReader reader = new PipedReader();
            PipedWriter writer2 = new PipedWriter(reader);
            
            System.out.println("Unconnected PipedWriter created");
            System.out.println("Connected PipedWriter created");
            
            writer1.close();
            writer2.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了创建 PipedWriter 的不同方法。第一个未连接,必须稍后连接。第二个预先连接到 PipedReader。完成后,始终关闭管道的两端以释放资源。

将 PipedWriter 连接到 PipedReader

未连接的 PipedWriter 必须在使用前连接到 PipedReader。可以使用 connect 方法建立连接。为了成功连接,两端都必须处于未连接状态。

Main.java
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            PipedWriter writer = new PipedWriter();
            PipedReader reader = new PipedReader();
            
            // Connect the writer to the reader
            writer.connect(reader);
            
            System.out.println("PipedWriter successfully connected to PipedReader");
            
            // Write some data
            writer.write("Hello from PipedWriter".toCharArray());
            
            // Read the data
            char[] buffer = new char[100];
            int bytesRead = reader.read(buffer);
            System.out.println("Read from PipedReader: " + 
                new String(buffer, 0, bytesRead));
            
            writer.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了如何在创建后将 PipedWriter 连接到 PipedReader。连接后,写入写入器的数据可供从读取器读取。必须在任何 I/O 操作之前建立连接。

使用 PipedWriter 进行线程通信

PipedWriter 常用作线程之间的通信。一个线程写入数据,而另一个线程读取数据。这提供了一种线程安全的方式在线程之间传递字符数据。

Main.java
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            PipedWriter writer = new PipedWriter();
            PipedReader reader = new PipedReader(writer);
            
            // Writer thread
            Thread writerThread = new Thread(() -> {
                try {
                    writer.write("Message from writer thread".toCharArray());
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            
            // Reader thread
            Thread readerThread = new Thread(() -> {
                try {
                    char[] buffer = new char[100];
                    int bytesRead = reader.read(buffer);
                    System.out.println("Reader thread received: " + 
                        new String(buffer, 0, bytesRead));
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            
            writerThread.start();
            readerThread.start();
            
            writerThread.join();
            readerThread.join();
            
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了使用 PipedWriter 和 PipedReader 进行线程间通信。写入线程发送消息,读取线程接收该消息。管道自动处理线程之间的同步。

使用 PipedWriter 写入数据

PipedWriter 提供了几种写入字符数据的方法。可以写入单个字符,也可以批量写入字符数组。所有写入操作都是线程安全的。

Main.java
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try (PipedWriter writer = new PipedWriter();
             PipedReader reader = new PipedReader(writer)) {
            
            // Write single character
            writer.write('A');
            
            // Write character array
            char[] data = {'B', 'C', 'D'};
            writer.write(data);
            
            // Write portion of array
            writer.write("EFGHIJKLMNOPQRSTUVWXYZ".toCharArray(), 0, 5);
            
            writer.flush();
            
            // Read all written data
            char[] buffer = new char[100];
            int bytesRead = reader.read(buffer);
            System.out.println("Received data: " + 
                new String(buffer, 0, bytesRead));
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例展示了使用 PipedWriter 写入数据的不同方式。可以写入单个字符、完整数组和部分数组。flush 方法确保所有写入的数据立即可供读取器使用。

处理管道中断错误

当连接的 PipedReader 关闭或遇到错误时,PipedWriter 将对后续操作抛出 IOException。这被称为“管道中断”情况。

Main.java
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            PipedWriter writer = new PipedWriter();
            PipedReader reader = new PipedReader(writer);
            
            // Close reader before writing
            reader.close();
            
            try {
                writer.write("Test".toCharArray());
                System.out.println("Write succeeded unexpectedly");
            } catch (IOException e) {
                System.out.println("Caught expected IOException: " + 
                    e.getMessage());
            }
            
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了管道中断的情况。当读取器关闭时,任何尝试写入写入器的操作都将抛出 IOException。在使用管道流时,适当的错误处理至关重要。

来源

Java PipedWriter 类文档

在本文中,我们介绍了 Java PipedWriter 类的基本方法和特性。了解这些概念对于使用 Java 应用程序中的字符流实现线程间通信至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员,在这一领域拥有多年的经验。我从 2007 年开始撰写编程文章,至今已撰写了 1,400 多篇文章和 8 本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程