Java 番石榴;合并多个文件并跳过重复的标题

Java 番石榴;合并多个文件并跳过重复的标题,java,file,guava,Java,File,Guava,我正在努力做到以下几点 假设我们有两个文件——文件1和文件2,内容如下 文件1: header d1 d2 文件2: header d3 d4 那么合并的文件应该是 输出文件: header d1 d2 d3 d4 请注意,我们正在跳过第二个文件的头。我使用Guava用Java编写了以下代码 LinkedList<InputSupplier<BufferedReader>> listOfSuppliers = new Lin

我正在努力做到以下几点

假设我们有两个文件——文件1和文件2,内容如下

文件1:

header
d1
d2
文件2:

header
d3
d4
那么合并的文件应该是

输出文件:

header
d1
d2
d3
d4
请注意,我们正在跳过第二个文件的头。我使用Guava用Java编写了以下代码

    LinkedList<InputSupplier<BufferedReader>> listOfSuppliers = 
                new LinkedList<InputSupplier<BufferedReader>>();

        boolean firstFile = true;
        for (Path path : inputPaths) {

            InputSupplier<BufferedReader> reader = newBufferedReaderSupplier(fs.open(path));
            if (!firstFile) {
                String ignored = reader.getInput().readLine();
                LOGGER.info("Ignored header from the second file " + ignored);
            }
            listOfSuppliers.add(reader);
            firstFile = false;
        }

        InputSupplier<Reader> combined = CharStreams.join(listOfSuppliers);
        OutputSupplier<OutputStreamWriter> outputStream 
                = Files.newWriterSupplier(output, Charsets.UTF_8, false);
        CharStreams.copy(combined, outputStream);
LinkedList供应商列表=
新建LinkedList();
布尔值firstFile=true;
用于(路径:输入路径){
InputSupplier reader=NewBufferederSupplier(fs.open(path));
如果(!firstFile){
字符串忽略=reader.getInput().readLine();
info(“从第二个文件忽略的头”+忽略);
}
供应商列表。添加(读卡器);
firstFile=false;
}
InputSupplier combined=CharStreams.join(供应商列表);
输出供应商输出流
=Files.newWriterSupplier(输出,Charsets.UTF_8,false);
复制(组合,输出流);
这段代码的问题是,当我们跳过头时,输出文件没有来自第二个文件的内容。我认为BufferedReader正在做一些导致整个文件被忽略的事情


你知道怎么解决这个问题吗?

恐怕全错了。从
InputSupplier.getInput()
javadoc:

与Iterable#迭代器类似,可以重复调用此方法以获得到相同底层资源的独立通道

这与你在美国所做的恰恰相反

String ignored = reader.getInput().readLine();
我猜,你们的输入供应商不遵守合同。如果它这样做了,上面的行将是禁止操作的。此外,它将使流保持打开状态。1

你从来没有说过你的文件很大,所以通过
files.readLines
读取所有文件,手动删除除第一行以外的所有文件的标题行,然后进行连接是最好的方法


如果您发现它效率低下,请注意,最耗时的部分可能是字节到字符和反向转换。对于UTF-8(以及许多其他编码),可以使用
InputStream
(注意
BufferedReader
将“\r”、“\n”或“\r\n”中的任何一个视为换行符)跳过第一行。但要当心这件事



1虽然供应商的设计是为了防止资源泄漏,但他们并没有神奇的方法来实现这一点。它们在Byte/CharStreams方法中的使用确保了一切都被关闭。

我不确定Guava类,但是Java NIO的
Files
有一个
readAllLines
方法返回一个
列表。在每个文件上使用它。清除第二行的第一行并附加两个列表。然后将它们写入一个文件。