1. 概述

在这个简短教程中,我们将探讨如何在Java中将PrintStream转换为String

我们首先使用核心Java方法,然后会看到如何利用Apache Commons IO等外部库来实现相同的目标。

2. PrintStream是什么

在Java中,PrintStream输出流,它提供了一种方便的方式来打印和格式化数据。它配备了一系列用于打印和格式化不同类型数据的方法,如println()printf()

与其他输出流不同,它从不抛出IOException。但在出现错误时,它会设置一个标志,可以通过checkError()方法进行检查。

现在我们知道PrintStream是什么了,接下来让我们看看如何将其转换为字符串。

3. 使用ByteArrayOutputStream

简而言之,ByteArrayOutputStream是一个输出流,数据会被写入到字节数组中。

通常,我们可以通过捕获PrintStream的输出,然后将捕获的字节转换为字符串来实现这一点。下面是实际操作的例子:

public static String usingByteArrayOutputStreamClass(String input) throws IOException {
    if (input == null) {
        return null;
    }

    String output;
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);

        output = outputStream.toString();
    }

    return output;
}

如图所示,我们创建了一个PrintStream对象,传递了ByteArrayOutputStream到构造函数中。

然后,我们使用print()方法向PrintStream写入输入字符串。

最后,我们使用ByteArrayOutputStream类的toString()方法将输入转换为String对象。

现在,让我们通过测试用例验证这一点:

@Test
public void whenUsingByteArrayOutputStreamClass_thenConvert() throws IOException {
    assertEquals("test", PrintStreamToStringUtil.usingByteArrayOutputStreamClass("test"));
    assertEquals("", PrintStreamToStringUtil.usingByteArrayOutputStreamClass(""));
    assertNull(PrintStreamToStringUtil.usingByteArrayOutputStreamClass(null));
}

正如上图所示,我们的方法成功地将PrintStream转换为了字符串。

4. 使用自定义输出流

另一种解决方案是使用OutputStream类的自定义实现。

本质上,OutputStream是所有表示字节输出流的类的超类,包括ByteArrayOutputStream

首先,考虑CustomOutputStream的静态内部类:

private static class CustomOutputStream extends OutputStream {

    private StringBuilder string = new StringBuilder();

    @Override
    public void write(int b) throws IOException {
        this.string.append((char) b);
    }

    @Override
    public String toString() {
        return this.string.toString();
    }
}

在这里,我们使用StringBuilder实例逐字写入给定的数据,并重写了toString()方法以获取StringBuilder对象的字符串表示。

接下来,让我们在前一节的示例中重用相同的代码,但这次我们将使用我们自己的自定义实现,而不是ByteArrayOutputStream

public static String usingCustomOutputStream(String input) throws IOException {
    if (input == null) {
        return null;
    }

    String output;
    try (CustomOutputStream outputStream = new CustomOutputStream(); PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);

        output = outputStream.toString();
    }

    return output;
}

现在,让我们添加另一个测试用例来确认一切按预期工作:

@Test
public void whenCustomOutputStream_thenConvert() throws IOException {
    assertEquals("world", PrintStreamToStringUtil.usingCustomOutputStream("world"));
    assertEquals("", PrintStreamToStringUtil.usingCustomOutputStream(""));
    assertNull(PrintStreamToStringUtil.usingCustomOutputStream(null));
}

5. 使用Apache Commons IO

另一种选择是使用Apache Commons IO库来达到同样的目的。

首先,我们需要在pom.xml文件中添加Apache Commons IO的依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version>
</dependency>

Apache Commons IO提供了其自己的ByteArrayOutputStream版本。这个类带有toByteArray()方法,可以获取数据作为字节数组。

让我们实践一下:

public static String usingApacheCommonsIO(String input) {
    if (input == null) {
        return null;
    }

    org.apache.commons.io.output.ByteArrayOutputStream outputStream = new org.apache.commons.io.output.ByteArrayOutputStream();
    try (PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);
    }

    return new String(outputStream.toByteArray());
}

简单来说,我们使用toByteArray()方法从输出流获取字节数组,然后将返回的数组传递给String构造函数。

这里的一个重要区别是,与Java不同,我们不需要关闭ByteArrayOutputStream

这个解决方案同样有效,如单元测试所示:

@Test
public void whenUsingApacheCommonsIO_thenConvert() {
    assertEquals("hello", PrintStreamToStringUtil.usingApacheCommonsIO("hello"));
    assertEquals("", PrintStreamToStringUtil.usingApacheCommonsIO(""));
    assertNull(PrintStreamToStringUtil.usingApacheCommonsIO(null));
}

6. 总结

在这篇文章中,我们学习了如何将PrintStream转换为String

过程中,我们解释了如何使用核心Java方法,并展示了如何使用外部库,如Apache Commons IO。

如往常一样,本文中的代码可以在GitHub上找到:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-io-conversions-2