在 Java 中,如何使用 Google 的 guava CharStreams.toString 进程中的 inputStream?

Posted

技术标签:

【中文标题】在 Java 中,如何使用 Google 的 guava CharStreams.toString 进程中的 inputStream?【英文标题】:In Java, how can I use the inputStream from a process with Google's guava CharStreams.toString? 【发布时间】:2011-10-25 04:41:54 【问题描述】:

我正在执行一个进程,并希望将其输出读入一个字符串。我希望使用GuavaCharStreams.toString(InputSupplier<R> supplier),而不是处理try/catch/finally。不幸的是,Process 的getInputStream() 返回的流是InputStream 类型而不是InputSupplier。如何使用它来创建InputSupplier 以与 toString() 一起使用?

理想情况下我可以这样做:

CharStreams.toString(CharStreams.newReaderSupplier(process.getInputStream()))

但是您不能从 InputStream 构造 InputSupplier,我无法找到如何执行此操作。

【问题讨论】:

【参考方案1】:

应该这样做:

InputStream is = process.getInputStream();
String content = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
is.close();

这是一个完整用法的真实示例:

HttpURLConnection connection = null;
URL url;
InputStream is = null;
try 
  url = new URL("https://graph.facebook.com/oauth/access_token?client_id=" + appId + "&client_secret=" + appSecret + "&grant_type=client_credentials");
  connection = (HttpURLConnection) url.openConnection();
  connection.setRequestProperty("accept-encoding", "gzip");

  is = connection.getInputStream();
  String content = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
  String[] tokens = content.split("=");
  System.out.println(tokens[1]);
 catch (IOException e) 
  // TODO Auto-generated catch block
  e.printStackTrace();
 finally 
  if (is != null) try 
    is.close();
   catch (IOException e) 
  connection.disconnect();

我知道这并不是真正的问题,但为了比较起见,他是你使用 IOUtils 的方式 - IMO 更简洁:

HttpURLConnection connection = null;
URL url;
InputStream is = null;

try 
  url = new URL("https://graph.facebook.com/oauth/access_token?client_id=" + appId + "&client_secret=" + appSecret + "&grant_type=client_credentials");
  connection = (HttpURLConnection) url.openConnection();
  connection.setRequestProperty("accept-encoding", "gzip");

  is = connection.getInputStream();

  String value = IOUtils.toString(is);
  if (!Strings.isNullOrEmpty(value)) 
    String[] splits = value.split("=");
    System.out.println(splits[1]);
  
 catch (IOException e) 

 finally 
  IOUtils.closeQuietly(is);
  connection.disconnect();

【讨论】:

【参考方案2】:

我还没有找到用番石榴做到这一点的方法。我相信开发人员有充分的理由这样做。在保持最小化的情况下,我得到的最接近的是:

 CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() 
        @Override
        public InputStream getInput() throws IOException 
            return inputStream;
        
    , Charsets.UTF_16));

我使用了来自 CharStreams 的 newReaderSupplier,因此您不必用 InputStreamReader 包装它。

【讨论】:

【参考方案3】:

正确的做法——以及 Guava 试图推动你做的事情——是更改为您提供 InputStream 的代码,改为为您提供 InputSupplier。

这样做的原因是这样,Guava 获取流,读取字符串,然后关闭它,在 Guava 关闭它之后你不能不小心使用它,因为你从来没有引用过 InputStream地方。这消除了很多潜在的错误。

另一个重载 CharStreams.toString(Readable) 不会关闭 Readable。如果您想拥有自己的特殊逻辑来关闭输入流,这是 Guava 让您这样做的方式。

Guava equivalent for IOUtils.toString(InputStream) 说得比我好。

【讨论】:

【参考方案4】:

到目前为止,这是我能做的最好的:

String commandOutput = CharStreams.toString(new InputSupplier<InputStreamReader>() 
    public InputStreamReader getInput() throws IOException 
        return new InputStreamReader(process.getInputStream());
    
);

【讨论】:

【参考方案5】:

这个呢:

CharStreams.toString(new InputStreamReader(process.getInpusttream()))

它正在使用CharStreams.toString(Readable)

【讨论】:

这不会在完成后关闭流——它只会使用 InputSupplier 来关闭

以上是关于在 Java 中,如何使用 Google 的 guava CharStreams.toString 进程中的 inputStream?的主要内容,如果未能解决你的问题,请参考以下文章

Java中Io类-File类的构造方法

在 Java 中,如何使用 Google 的 guava CharStreams.toString 进程中的 inputStream?

您如何在 Java 中使用 Google App Engine 数据存储中的列表属性?

如何在 MATLAB 中识别数值数组中的断点

如何使用 Java + ChromeDriver 在 AWS Lambda 中运行 Google Chrome 进行 Selenium 测试

如何在本地使用 java 连接到带有 spark 的 Google 大查询?