【问题标题】:Row-based InputStream filtering基于行的 InputStream 过滤
【发布时间】:2018-08-21 09:35:05
【问题描述】:

我有一个通过 Java InputStream 连接的大文件,稍后我会将 InputStream 作为参数提供给函数。

InputStream inputStream = new FileInputStream( ... );

但我希望将我的 InputStream 减少/过滤到行的子集;我的数据格式为:

X,Y

X,Y

X,Y

我希望 InputStream 仅包含此 csv 文件中的第二个元素,即 Y- 我希望对我的流进行基于行的过滤。

我想在进行此类转换时保留记忆。

也许这种表示会更好地解释我的要求:

inputStream -(按行过滤)->过滤输入流

然后我将filteredInputStream作为参数传递给我的函数。

执行此操作的最佳做​​法是什么?我应该将一个流连接到另一个流以执行此类过滤吗?

【问题讨论】:

  • 请求图书馆是题外话。只需谷歌搜索“Java CSV 解析器”。
  • 我已更改以表明我正在寻找一种最佳实践方法来帮助解决我的问题。我看不出您的 Google 搜索字词有什么帮助。
  • InputStream 中没有一行这样的东西。
  • 我假设 InputStream 被转换为 Java 8 Stream/List ?您的问题中缺少此内容

标签: java stream java-stream


【解决方案1】:

您可以尝试通过提供自己的 FilterInputStream 实现来过滤 InputStream。在里面你可以覆盖读取的方法,这样你就可以解析读取的结果,只返回你想要传递给下一个方法的数据。

或者,或者,您可以使用 CSV-Parser e.g. the one of apache commons 并且只将 Y 元素传递给 sub 方法。这应该更容易,但我们都不知道您的其余代码是什么样的,所以这只是一个假设。

【讨论】:

  • 我正在使用一个库,它只将 inputStream 作为其函数的参数。所以我想将一个经过过滤的 inputStream 传递给它。我可以用 CSVParser 做到这一点吗?
  • 并非如此。好的,这就是我所说的“只是一个假设”,如果它更容易的话。因此,您可以尝试编写自己的 FilteredInputStream,或者使用 CSV Parser 解析元素并根据结果创建自己的 InputStream。
  • 例如使用 ByteArrayInputStream。看过here
【解决方案2】:

您说的是流式传输文件,所以我认为最好使用 Files.line()

// Use try-with-resource to auto close stream
try (Stream<String> lines = Files.lines(Path.getName("your/path"))) { 
    List<String> stringYs = 
            s.map(l -> l.split(","))
             .filter(a -> a.length >= 2) // You may ensure that the string has two parts
             .map(a -> a[1]) // Get the second part, which is "Y"
             .collect(toList());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    相关资源
    最近更新 更多