ZetCode

Java FilterOutputStream 类

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

java.io.FilterOutputStream 类是输出流过滤器的基类。它封装另一个输出流并转换写入的数据。此类用作所有过滤输出流的超类。

FilterOutputStream 扩展了 OutputStream,并提供了一种在输出数据到达目的地之前对其进行修改的方法。常见的子类包括 BufferedOutputStreamDataOutputStreamPrintStream。该类本身不执行任何转换。

FilterOutputStream 类概述

FilterOutputStream 将所有请求委托给封装的输出流。它为构建输出流过滤器提供了基础。此类包含用于写入字节以及刷新/关闭流的方法。

public class FilterOutputStream extends OutputStream {
    protected OutputStream out;
    public FilterOutputStream(OutputStream out);
    public void write(int b);
    public void write(byte[] b);
    public void write(byte[] b, int off, int len);
    public void flush();
    public void close();
}

上面的代码显示了 FilterOutputStream 的结构。受保护的 out 字段保存了封装的流。所有写入操作都转发到此流。子类重写方法以添加功能。

创建 FilterOutputStream

要创建 FilterOutputStream,您必须提供一个现有的 OutputStream 来封装。构造函数将此流存储在受保护的 out 字段中。所有操作都将委托给它。

Main.java
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Main {

    public static void main(String[] args) {
        try {
            OutputStream fileStream = new FileOutputStream("output.txt");
            FilterOutputStream filterStream = new FilterOutputStream(fileStream);
            
            System.out.println("FilterOutputStream created successfully");
            
            filterStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了基本的 FilterOutputStream 创建。该流封装了一个 FileOutputStream。请注意,该类本身不会修改数据。始终关闭流以正确释放系统资源。

使用 FilterOutputStream 写入数据

FilterOutputStream 提供了三种写入方法。这些方法镜像了 OutputStream 中的方法。所有调用都转发到封装的流。子类可以重写这些方法以添加功能。

Main.java
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try (FilterOutputStream fos = 
                new FilterOutputStream(new FileOutputStream("data.bin"))) {
            
            // Write single byte
            fos.write(65); // ASCII 'A'
            
            // Write byte array
            byte[] data = {66, 67, 68}; // B, C, D
            fos.write(data);
            
            // Write portion of array
            byte[] moreData = {69, 70, 71, 72}; // E, F, G, H
            fos.write(moreData, 1, 2); // Writes F, G
            
            System.out.println("Data written successfully");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了使用 FilterOutputStream 写入数据的不同方式。try-with-resources 确保了正确的流关闭。输出文件将包含字节 "ABCDFG"。每个写入操作都直接传递到基础流。

创建自定义 FilterOutputStream

FilterOutputStream 的真正威力来自于对其进行子类化以创建自定义过滤器。您可以重写写入方法以在数据到达基础流之前转换数据。这可以实现各种处理管道。

Main.java
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

class UppercaseFilter extends FilterOutputStream {
    
    public UppercaseFilter(OutputStream out) {
        super(out);
    }
    
    @Override
    public void write(int b) throws IOException {
        // Convert lowercase letters to uppercase
        if (b >= 'a' && b <= 'z') {
            b = b - ('a' - 'A');
        }
        super.write(b);
    }
}

public class Main {
    public static void main(String[] args) {
        try (UppercaseFilter uf = 
                new UppercaseFilter(new FileOutputStream("output.txt"))) {
            
            String text = "Hello FilterOutputStream!";
            byte[] bytes = text.getBytes();
            
            uf.write(bytes);
            System.out.println("Data written with uppercase filter");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例创建了一个自定义的 UppercaseFilter,它将小写字母转换为大写字母。该过滤器重写了 write(int) 方法来执行转换。输出文件将包含 "HELLO FILTEROUTPUTSTREAM!"。

刷新和关闭流

FilterOutputStream 提供了 flushclose 方法。这些方法确保数据被写入并且资源被释放。这些方法转发到基础流。完成时务必关闭流。

Main.java
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        FilterOutputStream fos = null;
        try {
            fos = new FilterOutputStream(new FileOutputStream("flush.txt"));
            
            // Write some data
            fos.write("Testing flush".getBytes());
            
            // Force data to be written
            fos.flush();
            System.out.println("Data flushed to file");
            
            // Write more data
            fos.write("\nMore data".getBytes());
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    System.out.println("Stream closed");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

此示例演示了手动刷新和关闭 FilterOutputStreamflush 确保数据立即写入。finally 块保证即使发生异常也会关闭流。这可以防止资源泄漏。

与其他流结合使用

FilterOutputStream 可以与其他流类结合使用,以创建处理管道。这是 Java I/O 的一个强大功能。每个过滤器都会向数据添加自己的转换。

Main.java
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;

class HexFilter extends FilterOutputStream {
    
    public HexFilter(OutputStream out) {
        super(out);
    }
    
    @Override
    public void write(int b) throws IOException {
        String hex = Integer.toHexString(b);
        super.write(hex.getBytes());
        super.write(' '); // Add space separator
    }
}

public class Main {
    public static void main(String[] args) {
        try (HexFilter hf = new HexFilter(
                new BufferedOutputStream(
                new DataOutputStream(
                new FileOutputStream("hexdata.txt"))))) {
            
            byte[] data = {10, 20, 30, 40, 50};
            hf.write(data);
            
            System.out.println("Data written in hex format");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例创建了一个包含三个层的管道:FileOutputStreamDataOutputStreamBufferedOutputStream 和我们的自定义 HexFilter。十六进制过滤器将字节转换为其十六进制表示形式。缓冲流通过减少 I/O 操作来提高性能。

来源

Java FilterOutputStream 类文档

在本文中,我们探讨了 FilterOutputStream 类及其在 Java I/O 操作中的用法。我们已经了解了如何创建自定义过滤器并将它们与其他流类结合使用,以实现强大的数据处理。

作者

我的名字是 Jan Bodnar,我是一位敬业的程序员,在该领域拥有多年的经验。我于 2007 年开始撰写编程文章,此后撰写了超过 1,400 篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程