将InputStream读取/转换为String [java]


Answers

这是一个只使用标准Java库的方法(注意流不关闭,YMMV)。

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”)。

帽子提示也去雅各,曾经指向我说的文章。

编辑:感谢来自Patrick的建议,使处理空输入流时更强大的功能。 多一个编辑:不要尝试/抓住,帕特里克的方式更简洁。

Question

如果你有java.io.InputStream对象,你应该如何处理这个对象并产生一个String

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

采取InputStream并将其转换为String的最简单方法是什么?

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



Apache Commons允许:

String myString = IOUtils.toString(myInputStream, "UTF-8");

当然,你也可以选择除UTF-8之外的其他字符编码。

另请参阅:( 文档




这个怎么样?

InputStream in = /* your InputStream */;
StringBuilder sb=new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;

while((read=br.readLine()) != null) {
    //System.out.println(read);
    sb.append(read);   
}

br.close();
return sb.toString();



这是我的纯Java和Android解决方案,效果很好...

public String readFullyAsString(InputStream inputStream, String encoding)
        throws IOException {
    return readFully(inputStream).toString(encoding);
}    

public byte[] readFullyAsBytes(InputStream inputStream)
        throws IOException {
    return readFully(inputStream).toByteArray();
}    

private ByteArrayOutputStream readFully(InputStream inputStream)
        throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        baos.write(buffer, 0, length);
    }
    return baos;
}



怎么样:

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

public static String readInputStreamAsString(InputStream in) 
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }        
    return buf.toString();
}



我会使用一些Java 8技巧。

public static String streamToString(final InputStream inputStream) throws Exception {
    // buffering optional
    try
    (
        final BufferedReader br
           = new BufferedReader(new InputStreamReader(inputStream))
    ) {
        // parallel optional
        return br.lines().parallel().collect(Collectors.joining("\n"));
    } catch (final IOException e) {
        throw new RuntimeException(e);
        // whatever.
    }
}

基本上与其他答案相同,除了更简洁。




我经常进行一些时间测试,因为时间很重要。

我试图通过不同的方式将响应转换为字符串3。 (如下所示)
为了可读性,我省略了try / catch块。

为了给出上下文,这是所有3种方法的前面的代码:

   String response;
   String url = "www.blah.com/path?key=value";
   GetMethod method = new GetMethod(url);
   int status = client.executeMethod(method);

1)

 response = method.getResponseBodyAsString();

2)

InputStream resp = method.getResponseBodyAsStream();
InputStreamReader is=new InputStreamReader(resp);
BufferedReader br=new BufferedReader(is);
String read = null;
StringBuffer sb = new StringBuffer();
while((read = br.readLine()) != null) {
    sb.append(read);
}
response = sb.toString();

3)

InputStream iStream  = method.getResponseBodyAsStream();
StringWriter writer = new StringWriter();
IOUtils.copy(iStream, writer, "UTF-8");
response = writer.toString();

因此,在使用相同请求/响应数据的每个方法上运行500次测试之后,这里是数字。 再一次,这些是我的发现,你的发现可能不完全一样,但是我写这个来给其他人提供这些方法的效率差异的一些指示。

排名:
方法#1
方法#3 - 比#1慢2.6%
方法#2 - 比#1慢4.3%

任何这些方法都是获取响应并从中创建字符串的合适解决方案。




如果你喜欢冒险,你可以混合使用Scala和Java,并最终得到这个:

scala.io.Source.fromInputStream(is).mkString("")

混合Java和Scala代码和库有它的好处。

在这里看到完整的描述: 将InputStream转换为Scala中的字符串的习惯性方法




这是一个从org.apache.commons.io.IOUtils 源代码改编的答案,对于那些希望拥有apache实现但不想要整个库的人来说。

private static final int BUFFER_SIZE = 4 * 1024;

public static String inputStreamToString(InputStream inputStream, String charsetName)
        throws IOException {
    StringBuilder builder = new StringBuilder();
    InputStreamReader reader = new InputStreamReader(inputStream, charsetName);
    char[] buffer = new char[BUFFER_SIZE];
    int length;
    while ((length = reader.read(buffer)) != -1) {
        builder.append(buffer, 0, length);
    }
    return builder.toString();
}



这里是将完整的方法InputStreamString不使用任何第三方库。使用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();
}



科特林用户只需做:

println(InputStreamReader(is).readText())

readText()

是科特林标准库内置的扩展方法。




另外一个,对于所有的Spring用户:

import java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;

public String convertStreamToString(InputStream is) throws IOException { 
    return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}

在该实用程序的方法org.springframework.util.StreamUtils是类似于那些FileCopyUtils,但他们离开流开放完成时。




那么你可以为自己..程序是它并不复杂..

String Inputstream2String (InputStream is) throws IOException 
    {
        final int PKG_SIZE = 1024;
        byte[] data = new byte [PKG_SIZE];
        StringBuilder buffer = new StringBuilder(PKG_SIZE * 10);
        int size;

        size = is.read(data, 0, data.length);
        while (size > 0)
        {
            String str = new String(data, 0, size);
            buffer.append(str);
            size = is.read(data, 0, data.length);
        }
        return buffer.toString();
    }



您可以使用Apache的百科全书。在IOUtils你可以找到3个乐于助人实现了toString梅托德。

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input, String encoding)
            throws IOException {
        return toString(input, Charsets.toCharset(encoding));
}



番石榴提供的情况下,更短的有效autoclosing解决方案时,输入流来自于资源类路径(这似乎是流行的任务):

byte[] bytes = Resources.toByteArray(classLoader.getResource(path));

要么

String text = Resources.toString(classLoader.getResource(path), StandardCharsets.UTF_8);

还有的一般概念ByteSourceCharSource那轻轻的开启和关闭流的照顾。

因此,例如,而不是明确地打开一个小文件读取其内容:

String content = Files.asCharSource(new File("robots.txt"), StandardCharsets.UTF_8).read();
byte[] data = Files.asByteSource(new File("favicon.ico")).read();

要不就

String content = Files.toString(new File("robots.txt"), StandardCharsets.UTF_8);
byte[] data = Files.toByteArray(new File("favicon.ico"));