将 InputStream 转换为 String

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在 Java 中,InputStream 类用于按顺序从文件中读取数据。为了将数据作为字符串使用,我们需要将 InputStream 转换为字符串。本实验将教你不同的方法将 InputStream 转换为字符串。

使用 InputStreamReader

InputStreamReader 类提供了一个 read() 方法,用于将数据从 InputStream 读取到字符数组中。我们可以将字符数组转换为字符串。在 ~/project 目录下创建一个新的 Java 源文件 InputStreamToString.java,内容如下:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        char[] charArray = new char[256];
        reader.read(charArray);
        return new String(charArray);
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

要运行代码,请打开终端,然后使用以下命令编译并运行代码:

javac InputStreamToString.java && java InputStreamToString

使用 InputStreamReader 和 BufferedReader 结合 StringBuilder

对于较大的输入,上一步的方法可能效率较低。我们可以使用 BufferedReader 包装 InputStreamReader 来提高效率。然后,使用 StringBuilder 对象将从 BufferedReader 读取的行追加起来。在 InputStreamToString.java 中的第一步之后添加以下代码:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        StringBuilder builder = new StringBuilder();
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            builder.append(line);
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 InputStreamReader 和 BufferedReader 而不使用 StringBuilder

我们可以通过使用 BufferedReader 类的 lines() 方法来简化操作。这种方法允许我们跳过将每一行追加到单独的 StringBuilder 实例的步骤。在 InputStreamToString.java 中的第二步之后添加以下代码:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String str = bufferedReader.lines().collect(Collectors.joining("\n"));
        return str;
    }

    public static void main(String[] args) {
        InputStream input = new ByteArrayInputStream("hello world".getBytes());
        String strFromInputStream = inputStreamToString(input);
        System.out.print("String from the Input Stream is: " + strFromInputStream);
    }
}

使用 InputStream 的 readAllBytes() 方法

InputStream 类在 Java 9 中引入了 readAllBytes() 方法。这种方法可以高效地将整个 InputStream 对象转换为字符串,仅需一行代码。然而,对于较大的输入,不建议使用此方法。在 InputStreamToString.java 中的第三步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        return new String(input.readAllBytes());
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 Scanner 类

我们也可以使用 Scanner 类,这是一个常用于读取和解析数据的类,来将输入流转换为字符串。在 InputStreamToString.java 中的第四步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Scanner scanner = new Scanner(input);
        StringBuilder builder = new StringBuilder();
        while (scanner.hasNext()) {
            builder.append(scanner.nextLine());
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 ByteArrayOutputStream

我们可以使用 java.io 包中的 ByteArrayOutputStream 类,将数据从输入流复制到字节数组中。然后,将字节数组写入 ByteArrayOutputStream。最后,使用 ByteArrayOutputStreamtoString() 方法获取字符串表示。在 InputStreamToString.java 中的第五步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[128];
        int length;
        while ((length = input.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, length);
        }
        return byteArrayOutputStream.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 java.nio 包

java.nio 包中,我们可以使用 Files.createTempFile 创建一个临时文件,并将数据从 InputStream 复制到该文件中。然后,我们可以将该临时文件的内容读取为字符串。在 InputStreamToString.java 中的第六步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Path file = Files.createTempFile(null, null);
        Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
        return new String(Files.readAllBytes(file));
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 Google Guava 库

Google Guava 库提供了 CharStreams 类来将 InputStream 转换为字符串。我们可以使用该类的 toString() 方法来实现这一点。该方法会接收一个 Readable 对象(例如 InputStreamReader),并将其中的数据读取为字符串。在 InputStreamToString.java 中的第七步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.google.common.io.CharStreams;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        try(InputStreamReader reader = new InputStreamReader(input)) {
            return CharStreams.toString(reader);
        }
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 Apache Commons IO

org.apache.commons.io 包中的 IOUtils 类也包含一个 toString() 方法。我们可以直接将 InputStream 对象传递给该方法,它会从中读取数据并转换为字符串。我们还需要指定一个 Charset。在 InputStreamToString.java 中的第八步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = IOUtils.toString(input, StandardCharsets.UTF_8.name());
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

使用 StringWriter 类与 Apache Commons IO

我们可以使用 java.io 包中的 StringWriter 类,并将 InputStream 的内容复制到 StringWriter 中。我们将使用 IOUtils 类的 copy() 方法来实现这一点。在 InputStreamToString.java 中的第九步之后添加以下代码:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            StringWriter sw = new StringWriter();
            IOUtils.copy(input, sw, StandardCharsets.UTF_8.name());
            String strFromInputStream = sw.toString();
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

总结

在本实验中,你学习了在 Java 中将 InputStream 转换为字符串的不同方法。你可以使用 ByteArrayOutputStreamBufferedReader 类来提高效率。Scanner 类也可用于将输入流转换为字符串。readAllBytes() 方法仅适用于较小的输入。我们可以使用 Google Guava 或 Apache Commons IO 等外部库来简化这一过程。请记住处理异常并关闭 InputStream,以避免资源泄漏。

您可能感兴趣的其他 Java 教程