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


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

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

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

当前回答

InputStream is = Context.openFileInput(someFileName); // whatever format you have

ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] b = new byte[8192];
for (int bytesRead; (bytesRead = is.read(b)) != -1;) {
    bos.write(b, 0, bytesRead);
}

String output = bos.toString(someEncoding);

其他回答

InputStream is = Context.openFileInput(someFileName); // whatever format you have

ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] b = new byte[8192];
for (int bytesRead; (bytesRead = is.read(b)) != -1;) {
    bos.write(b, 0, bytesRead);
}

String output = bos.toString(someEncoding);

如果不能使用Commons IO(FileUtils/IOUtils/CopyUtils),下面是一个使用BufferedReader逐行读取文件的示例:

public class StringFromFile {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFile.class.getResourceAsStream("file.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(is/*, "UTF-8"*/));
        final int CHARS_PER_PAGE = 5000; //counting spaces
        StringBuilder builder = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(String line=br.readLine(); line!=null; line=br.readLine()) {
                builder.append(line);
                builder.append('\n');
            }
        } 
        catch (IOException ignore) { }

        String text = builder.toString();
        System.out.println(text);
    }
}

或者,如果你想要原始速度,我会根据Paul de Vrieze的建议(避免使用StringWriter(内部使用StringBuffer))提出一个变体:

public class StringFromFileFast {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFileFast.class.getResourceAsStream("file.txt");
        InputStreamReader input = new InputStreamReader(is/*, "UTF-8"*/);
        final int CHARS_PER_PAGE = 5000; //counting spaces
        final char[] buffer = new char[CHARS_PER_PAGE];
        StringBuilder output = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(int read = input.read(buffer, 0, buffer.length);
                    read != -1;
                    read = input.read(buffer, 0, buffer.length)) {
                output.append(buffer, 0, read);
            }
        } catch (IOException ignore) { }

        String text = output.toString();
        System.out.println(text);
    }
}
String inputStreamToString(InputStream inputStream, Charset charset) throws IOException {
    try (
            final StringWriter writer = new StringWriter();
            final InputStreamReader reader = new InputStreamReader(inputStream, charset)
        ) {
        reader.transferTo(writer);
        return writer.toString();
    }
}

纯Java标准库解决方案-无库自Java 10以来-Reader#transferTo(Java.io.Writer)无环溶液无新行字符处理

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

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

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

考虑到文件,首先应该获得java.io.Reader实例。然后可以将其读取并添加到StringBuilder中(如果我们不在多个线程中访问StringBuffer,我们就不需要StringBuffer了,StringBuilder速度更快)。这里的技巧是我们在块中工作,因此不需要其他缓冲流。块大小被参数化以用于运行时性能优化。

public static String slurp(final InputStream is, final int bufferSize) {
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    try (Reader in = new InputStreamReader(is, "UTF-8")) {
        for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
                break;
            out.append(buffer, 0, rsz);
        }
    }
    catch (UnsupportedEncodingException ex) {
        /* ... */
    }
    catch (IOException ex) {
        /* ... */
    }
    return out.toString();
}