如果您有java.io.InputStream对象,应该如何处理该对象并生成String?


假设我有一个包含文本数据的InputStream,我想将其转换为String,例如,我可以将其写入日志文件。

获取InputStream并将其转换为字符串的最简单方法是什么?

public String convertStreamToString(InputStream is) {
// ???
}

当前回答

Kotlin用户只需:

println(InputStreamReader(is).readText())

鉴于

readText()

是Kotlin标准库的内置扩展方法。

其他回答

此外,您还可以从指定的资源路径获取InputStream:

public static InputStream getResourceAsStream(String path)
{
    InputStream myiInputStream = ClassName.class.getResourceAsStream(path);
    if (null == myiInputStream)
    {
        mylogger.info("Can't find path = ", path);
    }

    return myiInputStream;
}

要从特定路径获取InputStream,请执行以下操作:

public static URL getResource(String path)
{
    URL myURL = ClassName.class.getResource(path);
    if (null == myURL)
    {
        mylogger.info("Can't find resource path = ", path);
    }
    return myURL;
}

这里有一种仅使用标准Java库的方法(请注意,流没有关闭,您的里程可能会有所不同)。

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

我从“愚蠢的扫描仪技巧”一文中学会了这个技巧。它工作的原因是因为Scanner迭代流中的令牌,在这种情况下,我们使用“输入边界的开始”(\A)来分离令牌,从而为流的整个内容只提供一个令牌。

注意,如果您需要明确输入流的编码,可以向Scanner构造函数提供第二个参数,指示要使用的字符集(例如“UTF-8”)。

雅各布也收到了帽子提示,他曾向我指出了上述文章。

如果您正在使用Google Collections/Guava,您可以执行以下操作:

InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);

请注意,InputStreamReader的第二个参数(即Charsets.UTF_8)不是必需的,但如果您知道编码(您应该这样做!)

这里是在不使用任何第三方库的情况下将InputStream转换为String的完整方法。对于单线程环境使用StringBuilder,否则使用StringBuffer。

public static String getString( InputStream is) throws IOException {
    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = is.read()) != -1)
        sb.append((char)ch);
    return sb.toString();
}

与Okio一起:

String result = Okio.buffer(Okio.source(inputStream)).readUtf8();