Java IOUtils.toString(InputStream) 的番石榴等价物

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4185665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 12:48:50  来源:igfitidea点击:

Guava equivalent for IOUtils.toString(InputStream)

javaioinputstreamguava

提问by Sean Patrick Floyd

Apache Commons IOhas a nice convenience method IOUtils.toString()to read an InputStreamto a String.

Apache Commons IO有一个非常方便的方法IOUtils.toString()来读取InputStream字符串。

Since I am trying to move away from Apache Commons and to Guava: is there an equivalent in Guava? I looked at all classes in the com.google.common.iopackage and I couldn't find anything nearly as simple.

由于我试图从 Apache Commons 转移到GuavaGuava 中是否有等价物?我查看了com.google.common.io包中的所有类,几乎找不到任何简单的东西。

Edit:I understand and appreciate the issues with charsets. It just so happens that I know that all my sources are in ASCII (yes, ASCII, not ANSI etc.), so in this case, encoding is not an issue for me.

编辑:我理解并欣赏字符集的问题。碰巧我知道我所有的源都是 ASCII(是的,ASCII,而不是 ANSI 等),所以在这种情况下,编码对我来说不是问题。

采纳答案by ColinD

You stated in your comment on Calum's answer that you were going to use

您在对 Calum 回答的评论中表示您将使用

CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))

This code is problematic because the overload CharStreams.toString(Readable)states:

这段代码有问题,因为重载CharStreams.toString(Readable)状态:

Does not close the Readable.

不关闭Readable.

This means that your InputStreamReader, and by extension the InputStreamreturned by supplier.get(), will not be closed after this code completes.

这意味着在此代码完成后,您的InputStreamReader以及由InputStream返回的扩展supplier.get()名将不会关闭。

If, on the other hand, you take advantage of the fact that you appear to already have an InputSupplier<InputStream>and used the overload CharStreams.toString(InputSupplier<R extends Readable & Closeable>), the toStringmethod will handle both the creation and closing of the Readerfor you.

另一方面,如果您利用了一个事实,即您似乎已经拥有InputSupplier<InputStream>并使用了重载CharStreams.toString(InputSupplier<R extends Readable & Closeable>),则该toString方法将为您处理 的创建和关闭Reader

This is exactly what Jon Skeet suggested, except that there isn't actually any overload of CharStreams.newReaderSupplierthat takes an InputStreamas input... you have to give it an InputSupplier:

这正是 Jon Skeet 所建议的,除了实际上没有任何CharStreams.newReaderSupplier将 anInputStream作为输入的过载......你必须给它一个InputSupplier

InputSupplier<? extends InputStream> supplier = ...
InputSupplier<InputStreamReader> readerSupplier = 
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8);

// InputStream and Reader are both created and closed in this single call
String text = CharStreams.toString(readerSupplier);

The point of InputSupplieris to make your life easier by allowing Guava to handle the parts that require an ugly try-finallyblock to ensure that resources are closed properly.

重点InputSupplier是让 Guava 处理需要丑陋try-finally块的部分,以确保正确关闭资源,从而让您的生活更轻松。

Edit:Personally, I find the following (which is how I'd actually write it, was just breaking down the steps in the code above)

编辑:就个人而言,我发现以下内容(这就是我实际编写它的方式,只是分解了上面代码中的步骤)

String text = CharStreams.toString(
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));

to be farless verbose than this:

远远比这个更简洁:

String text;
InputStreamReader reader = new InputStreamReader(supplier.get(), 
    Charsets.UTF_8);
boolean threw = true;
try {
  text = CharStreams.toString(reader);
  threw = false;
}
finally {
  Closeables.close(reader, threw);
}

Which is more or less what you'd have to write to handle this properly yourself.

这或多或少是您必须自己编写才能正确处理此问题的内容。



Edit: Feb. 2014

编辑:2014 年 2 月

InputSupplierand OutputSupplierand the methods that use them have been deprecated in Guava 16.0. Their replacements are ByteSource, CharSource, ByteSinkand CharSink. Given a ByteSource, you can now get its contents as a Stringlike this:

InputSupplierOutputSupplier使用它们的方法在 Guava 16.0 中已被弃用。其接替者ByteSourceCharSourceByteSinkCharSink。给定 a ByteSource,您现在可以String像这样获取其内容:

ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();

回答by Calum

If you've got a Readableyou can use CharStreams.toString(Readable). So you can probably do the following:

如果你有一个Readable你可以使用CharStreams.toString(Readable). 因此,您可能可以执行以下操作:

String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );

Forces you to specify a character set, which I guess you should be doing anyway.

强制您指定一个字符集,我想您无论如何都应该这样做。

回答by Jon Skeet

Nearly. You could use something like this:

几乎。你可以使用这样的东西:

InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
    (streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);

Personally I don'tthink that IOUtils.toString(InputStream)is "nice" - because it always uses the default encoding of the platform, which is almost never what you want. There's an overload which takes the name of the encoding, but using names isn't a great idea IMO. That's why I like Charsets.*.

我个人认为这IOUtils.toString(InputStream)是“好” -因为它总是使用的平台,这是几乎从来没有你想要什么的默认编码。有一个采用编码名称的重载,但使用名称并不是一个好主意 IMO。这就是为什么我喜欢Charsets.*.

EDIT: Not that the above needs an InputSupplier<InputStream>as the streamSupplier. If you've already got the stream you can implement that easily enough though:

编辑:并不是说上面需要一个InputSupplier<InputStream>作为streamSupplier. 如果你已经有了流,你可以很容易地实现它:

InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
    @Override public InputStream getInput() {
        return stream;
    }
};

回答by Sean Patrick Floyd

Based on the accepted answer, here is a utility method that mocks the behavior of IOUtils.toString()(and an overloaded version with a charset, as well). This version should be safe, right?

根据接受的答案,这里有一个实用方法,它模拟IOUtils.toString()(以及带有字符集的重载版本)的行为。这个版本应该是安全的吧?

public static String toString(final InputStream is) throws IOException{
    return toString(is, Charsets.UTF_8);
}


public static String toString(final InputStream is, final Charset cs)
throws IOException{
    Closeable closeMe = is;
    try{
        final InputStreamReader isr = new InputStreamReader(is, cs);
        closeMe = isr;
        return CharStreams.toString(isr);
    } finally{
        Closeables.closeQuietly(closeMe);
    }
}

回答by husayt

UPDATE: Looking back, I don't like my old solution. Besides it is 2013 now and there are better alternatives available now for Java7. So here is what I use now:

更新:回顾过去,我不喜欢我的旧解决方案。此外现在是 2013 年,Java7 现在有更好的替代品。所以这是我现在使用的:

InputStream fis = ...;
String text;
try (  InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){
        text = CharStreams.toString(reader);
}

or if with InputSupplier

或者如果使用InputSupplier

InputSupplier<InputStreamReader> spl = ...
try (  InputStreamReader reader = spl.getInput()){
        text = CharStreams.toString(reader);
    }

回答by orip

EDIT(2015): Okiois the best abstraction and tools for I/O in Java/Android that I know of. I use it all the time.

编辑(2015 年):Okio是我所知道的 Java/Android 中最好的 I/O 抽象和工具。我用它所有的时间。

FWIW here's what I use.

FWIW 这是我使用的。

If I already have a stream in hand, then:

如果我手头已经有一个流,那么:

final InputStream stream; // this is received from somewhere
String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return stream;
    }
}, Charsets.UTF_8));

If I'm creating a stream:

如果我正在创建一个流:

String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return <expression creating the stream>;
    }
}, Charsets.UTF_8));

As a concrete example, I can read an Android text file asset like this:

作为一个具体的例子,我可以像这样读取一个 Android 文本文件资产:

final Context context = ...;
String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return context.getAssets().open("my_asset.txt");
    }
}, Charsets.UTF_8));

回答by ponomandr

Another option is to read bytes from Stream and create a String from them:

另一种选择是从 Stream 读取字节并从中创建一个字符串:

new String(ByteStreams.toByteArray(inputStream))
new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)

It's not 'pure' Guava, but it's a little bit shorter.

它不是“纯”番石榴,但它更短一些。

回答by TruMan1

For a concrete example, here's how I can read an Android text file asset:

举一个具体的例子,下面是我如何读取 Android 文本文件资产:

public static String getAssetContent(Context context, String file) {
    InputStreamReader reader = null;
    InputStream stream = null;
    String output = "";

    try {
        stream = context.getAssets().open(file);
        reader = new InputStreamReader(stream, Charsets.UTF_8);
        output = CharStreams.toString(reader);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    return output;
}

回答by Vadzim

There is much shorter autoclosing solution in case when input stream comes from classpath resource:

如果输入流来自类路径资源,则有更短的自动关闭解决方案:

URL resource = classLoader.getResource(path);
byte[] bytes = Resources.toByteArray(resource);
String text = Resources.toString(resource, StandardCharsets.UTF_8);

Uses Guava Resources, inspired by IOExplained.

使用 Guava资源,灵感来自IOExplained