将流转换为字符串 Java/Groovy

30

我从网上找到了这段代码。但是它好像只适用于4096字节,而且在我看来很丑陋。有没有更好的方法?顺便说一句,我实际上在使用Groovy...

String streamToString(InputStream input) {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        for (int n; (n = input.read(b)) != -1;) {
            out.append(new String(b, 0, n));
        }
        return out.toString();
    }

编辑:

我在Groovy中找到了更好的解决方案:

InputStream exportTemplateStream = getClass().getClassLoader().getResourceAsStream("export.template")
assert exportTemplateStream: "[export.template stream] resource not found"
String exportTemplate = exportTemplateStream.text
8个回答

56

有一些好的且快速的答案。然而我认为最好的答案是Groovy在InputStream中添加了一个"getText"方法,所以我只需要使用stream.text即可。并且关于4096的评论也很棒。


2
所以你是在询问之后查看了文档?至少你可以粘贴一个使用示例。 - Anon
1
当然,在我询问之后,我继续寻找,一开始我没有看到.text方法。以下是代码片段:InputStream exportTemplateStream = getClass().getClassLoader().getResourceAsStream("export.template") assert exportTemplateStream: "[export.template stream] resource not found" String exportTemplate = exportTemplateStream.text - phil swenson
够公平。但是正如我对其他人所说的那样:使用需要显式字符集的变体——默认字符集很少是你想要的。 - Anon

16

对于Groovy

filePath = ... //< a FilePath object
stream = filePath.read() //< InputStream object

// Specify the encoding, and get the String object
//content = stream.getText("UTF-16") 
content = stream.getText("UTF-8") 

InputStream类的参考文档

如果不指定编码,getText()方法将使用当前系统的编码(例如“UTF-8”)。


8
尝试使用Apache Commons中的IOUtils: IOUtils
String s = IOUtils.toString(inputStream, "UTF-8");

5

它会将输入分块为4096字节(4KB)的块,但实际字符串的大小不受限制,因为它会继续读取更多内容并将其附加到StringBuffer中。


4

您可以使用Scanner类轻松实现:

String streamToSring(InputStream input) {
    Scanner s = new Scanner(input);
    StringBuilder builder = new StringBuilder();
    while (s.hasNextLine()) {
        builder.append(s.nextLine() +"\n");
    }
    return builder.toString();
}

你需要传递一个字符集,否则你将会面临难以诊断的错误。 - Anon
@Anon,这段代码可能存在许多错误。该代码仅作为示例提供,不应在生产中使用。 - jjnguy
1
@jinguy - 展示有缺陷的代码是否能“改善互联网”?还是只会增加声望? - Anon
@jinguy - 如果有人来并采用了最高票答案的内容,而这会伤害到其他人,我不认为这会改善互联网。 - Anon
1
我的意思是,人们不应该直接从互联网上复制代码并将其直接用于他们的代码中。 - jjnguy

2
那段代码有一个错误:如果输入使用多字节字符编码,很可能一个字符会跨越两次读取(且无法转换)。它还有一个半错误,就是依赖于平台的默认编码。
相反,使用Jakarta Commons IO。特别是使用IOUtils.toString()版本,该版本接受一个InputStream并对其应用编码。

1
对于未来遇到类似问题的审阅者,请注意,无论是Apache的IOUtils还是Groovy的InputStream.getText()方法都需要流完成或关闭后才能返回。如果您正在使用持久流,则需要处理Phil最初发布的“丑陋”示例,或使用非阻塞IO。

0

你可以尝试类似于这样的东西

new FileInputStream( new File("c:/tmp/file.txt") ).eachLine { println it }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接