ZetCode

Java ByteArrayOutputStream 类

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

java.io.ByteArrayOutputStream 类实现了一个输出流,它将数据写入一个字节数组。缓冲区在写入数据时会自动增长。当你需要在将数据写入其他地方之前在内存中收集数据时,这个类很有用。

ByteArrayOutputStream 扩展了 OutputStream,并提供了将数据写入内部字节数组的方法。该类包括将缓冲区转换为字节数组或字符串的方法。不需要关闭此流,因为它不使用系统资源。

ByteArrayOutputStream 类概述

ByteArrayOutputStream 维护一个内部字节数组,该数组根据需要增长。关键方法包括写入操作、大小跟踪和缓冲区转换。该类是线程安全的,可以并发访问。

public class ByteArrayOutputStream extends OutputStream {
    public ByteArrayOutputStream();
    public ByteArrayOutputStream(int size);
    public synchronized void write(int b);
    public synchronized void write(byte[] b, int off, int len);
    public synchronized void writeTo(OutputStream out);
    public synchronized void reset();
    public synchronized byte[] toByteArray();
    public synchronized int size();
    public synchronized String toString();
    public synchronized String toString(String charsetName);
    public void close();
}

上面的代码显示了 ByteArrayOutputStream 提供的关键方法。这些方法允许将数据写入内存缓冲区并将其转换为各种格式。close 方法无效,因为没有使用系统资源。

创建 ByteArrayOutputStream

ByteArrayOutputStream 可以使用默认大小(32 字节)或自定义初始容量创建。缓冲区在需要时会自动增长。指定初始大小可以提高已知数据大小的性能。

Main.java
import java.io.ByteArrayOutputStream;

public class Main {

    public static void main(String[] args) {
        // Create with default buffer size
        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
        System.out.println("Default size: " + baos1.size());
        
        // Create with custom initial size (1024 bytes)
        ByteArrayOutputStream baos2 = new ByteArrayOutputStream(1024);
        System.out.println("Custom size: " + baos2.size());
        
        // Write some data to show buffer growth
        for (int i = 0; i < 100; i++) {
            baos1.write(i);
        }
        System.out.println("After writing 100 bytes: " + baos1.size());
    }
}

此示例演示了创建 ByteArrayOutputStream 的不同方式。第一个使用默认大小,而第二个指定了 1024 字节。当写入的数据超过初始容量时,缓冲区会自动增长。size 方法返回当前缓冲区内容长度。

将数据写入 ByteArrayOutputStream

ByteArrayOutputStream 提供了几种写入数据的方法。您可以写入单个字节或字节数组。所有写入操作都为了线程安全而同步。缓冲区会自动扩展以容纳写入的数据。

Main.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            
            // Write single byte
            baos.write(65); // ASCII 'A'
            
            // Write byte array
            byte[] data = {66, 67, 68}; // B, C, D
            baos.write(data);
            
            // Write portion of byte array
            byte[] moreData = {69, 70, 71, 72, 73}; // E, F, G, H, I
            baos.write(moreData, 1, 3); // Write F, G, H
            
            System.out.println("Buffer content: " + baos.toString());
            System.out.println("Buffer size: " + baos.size());
        }
    }
}

此示例显示了将数据写入 ByteArrayOutputStream 的不同方式。write 方法接受单个字节或字节数组。您还可以使用偏移量和长度参数写入数组的一部分。toString 方法使用平台默认字符集将缓冲区内容转换为字符串。

将缓冲区转换为字节数组

toByteArray 方法返回缓冲区当前内容的一个副本。当您需要将收集的数据作为字节数组访问时,这很有用。原始缓冲区保持不变,并且可以继续累积数据。

Main.java
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        // Write some data
        String text = "Hello, ByteArrayOutputStream!";
        baos.writeBytes(text.getBytes());
        
        // Get buffer content as byte array
        byte[] byteArray = baos.toByteArray();
        
        System.out.println("Byte array content: " + Arrays.toString(byteArray));
        System.out.println("Byte array length: " + byteArray.length);
        System.out.println("Original buffer size: " + baos.size());
        
        // Continue writing to original stream
        baos.writeBytes(" Additional data".getBytes());
        System.out.println("Updated buffer size: " + baos.size());
    }
}

此示例演示了将缓冲区内容转换为字节数组。toByteArray 方法创建一个包含当前内容的新数组。原始流保持活动状态,可以进行进一步的写入。当您需要同时累积数据和处理快照时,这很有用。

将缓冲区内容写入另一个流

writeTo 方法将整个缓冲区内容写入另一个 OutputStream。这对于传输收集的数据非常有效,而无需创建中间字节数组。该方法为了线程安全而同步。

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

public class Main {

    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        // Collect data in memory
        String data = "This data will be written to a file";
        baos.writeBytes(data.getBytes());
        
        try (FileOutputStream fos = new FileOutputStream("output.txt")) {
            // Write buffer content to file
            baos.writeTo(fos);
            System.out.println("Data written to file successfully");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        System.out.println("Buffer size after writeTo: " + baos.size());
    }
}

此示例显示了如何将缓冲区内容传输到另一个输出流。writeTo 方法有效地将所有收集的数据写入目标流。原始缓冲区在操作完成后保持不变。这对于在将数据写入文件或网络流之前在内存中收集数据很有用。

重置缓冲区

reset 方法清除缓冲区内容,将大小重置为零,同时保持相同的底层缓冲区容量。当你需要重用缓冲区时,这比创建一个新流更有效。

Main.java
import java.io.ByteArrayOutputStream;

public class Main {

    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        // Write initial data
        baos.writeBytes("Initial data".getBytes());
        System.out.println("After first write: " + baos.toString());
        System.out.println("Size: " + baos.size());
        
        // Reset the buffer
        baos.reset();
        System.out.println("After reset: " + baos.toString());
        System.out.println("Size: " + baos.size());
        
        // Write new data
        baos.writeBytes("New data".getBytes());
        System.out.println("After second write: " + baos.toString());
        System.out.println("Size: " + baos.size());
    }
}

此示例演示了使用 reset 方法清除缓冲区内容。重置后,缓冲区显示为空,但保留其容量。当你需要将流用于新数据而无需分配新内存时,这很有用。reset 不会缩小底层字节数组。

将缓冲区转换为字符串

ByteArrayOutputStream 提供了 toString 方法,用于将缓冲区内容转换为字符串。您可以使用平台默认字符集或指定一个字符集。当在内存中收集文本数据时,这很有用。

Main.java
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

public class Main {

    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        // Write data in different encodings
        try {
            baos.write("Hello ".getBytes("UTF-8"));
            baos.write("世界".getBytes("UTF-8"));
            
            // Convert to string using default charset
            System.out.println("Default charset: " + baos.toString());
            
            // Convert using specific charset
            System.out.println("UTF-8: " + baos.toString("UTF-8"));
            System.out.println("ISO-8859-1: " + baos.toString("ISO-8859-1"));
            
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了将缓冲区内容转换为字符串的不同方式。没有参数的 toString 方法使用平台默认字符集。指定字符集可确保一致的字符编码。请注意,某些字符集可能不支持缓冲区中的所有字符。

来源

Java ByteArrayOutputStream 类文档

在本文中,我们涵盖了 Java ByteArrayOutputStream 类的基本方法和特性。理解这些概念对于在 Java 应用程序中使用内存中的字节数据收集和操作至关重要。

作者

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

列出所有Java教程