2016-09-21 91 views
1

我有一个函数将会收到Stream<String>。该流表示文件中的行(由Files.lines(somePath)调用)。文件本身实际上是许多文件拼接成一个文件,这样的事情:将字符串流转换为字符串分组列表的有效方法

 
__HEADER__ # for file 1 
data 
more data 
... 
__HEADER__ # file 2 starts here 
some more data... 
... 

我需要将流转换为多个物理文件上的文件系统。

我已经尝试了简单的办法,沿着线的东西:

String allLinesJoined = lineStream.collect(Collectors.joining()); 
// This solution seems to get stuck on the line above^
String files[] = allLinesJoined.split("__HEADER__"); 
for (fileStr : files) 
{ 
    // This function will write each fileStr to a separate file 
    // (filename is determined by contents of fileStr) 
    writeToPhysicalFile(fileStr); 
} 

但输入文件是约〜300 MB(并能得到较大),这解决方案似乎停留在第一个GET线。如果我有更多的记忆,也许它会完成......?

如果我的出发点是Stream<String>,还是应该开始进行其他更改,以便这部分代码只需逐行读取文件,而无需使用流API,那么还有更好的方法吗?

(该行的顺序此事确实,在这些文件中的上下文中)

TL;博士

我需要打开表示为Stream<String>一个大文件中的许多小文件。每个小文件以__HEADER__和所有行后开头,直到下一个__HEADER__。当前的库使用流提供文件,但它甚至值得试图用流来做到这一点,或者如果我改变库以提供非流功能,我的生活会更容易吗?

+0

基于冲突的答案可能有一些混乱,你的最终目标是什么(至少我很困惑)。我理解这个问题,但不是理想的解决方案 –

+1

@ChrisThompson:我也意识到了这一点,并且我认为我的最新编辑更加清晰。 – FrustratedWithFormsDesigner

+0

流是_really_不是为此设计的。它们专为不关心流如何单独分块的操作而设计。 –

回答

2

杀死了整个流的想法。

尝试的forEach():

Stream<String> lineStream = Files.lines(Paths.get("your_file")); 

    lineStream.forEachOrdered((s) -> { 
     if ("HEADER".equals(s)) { 
      // create new file 
     } 
     else { 
      // append to this file 
     } 
    }); 
+0

是的,它并不适用于流的思想,但基于此我可以很好地工作,它比重写底层代码更快,并且它的表现也非常好。 :) – FrustratedWithFormsDesigner

+1

不是我亲自批评你,无论如何!如果每个人都知道所有的解决方案,那么不会有StackOverflow开始。 –

相关问题