2015-10-18 88 views
0

我正在逐行讀取多個文件,發現SequenceInputStream方便。以下是我如何使用它:使用SequenceInputStream時逐行讀取多個文件的問題

try (
    InputStream in = new SequenceInputStream(new FileInputStream(file1),new FileInputStream(file2)); 
    Scanner reader = new Scanner(source)) { 
    while (reader.hasNext()) { 
     System.out.println(reader.nextLine()); 
    } 
} 

但它有一個奇怪的問題。讓說:

文件1

a 
b 

文件2

c 
d 

然後執行的代碼將輸出:

a 
bc 
d 

看來,它不區分林es從單獨的文件,有沒有辦法解決這個問題? (是的,我真的需要多InputStreams合併爲一個)

+0

也許'file1'不會以換行符結束。 –

+0

@JamesKPolk這是一個黑客。它會「工作」,但通常情況下,你會爲​​你將要讀取的提供的輸入文件寫入換行符嗎?這只是瘋狂的 – Benedictus

+0

沒有換行符爲什麼你會期望一個單獨的行?掃描儀如何知道一個文件何時結束,並且下一個文件是否源於單個InputStream? –

回答

2

SequenceInputStream隱藏了所有的包文件EOF人物除了最後一個文件:

public int read() throws IOException { 
    if (in == null) { 
     return -1; 
    } 
    int c = in.read(); 
    if (c == -1) { 
     nextStream(); 
     return read(); 
    } 
    return c; 
} 

因此,如果文件不結束一個新行,那麼file2的第一行將被附加到file1的最後一行。

如果您確實需要使用一個inputStream,並且您需要分隔線來分隔每個文件,那麼您可能必須編寫自己的InputStream實現來檢查是否有換行符作爲文件的最後一行,並且如果不是,則插入一個作爲read()方法的一部分。

1

如果要排序多個數據流,並要確保在line separator每一端,在FilterInputStream如果沒有過濾的流中,在年底返回一個額外的行分隔符,包裝每個流。

+0

小心添加一個例子? – Benedictus

1

正如其他答案指出的,我可以創建自己的SequenceInputStream實現,或將每個流包裝爲FilterInputStream。不過我想我找到了一個更簡單的解決方案:只需在我的文件流之間插入提供endline的流。

InputStream in = new SequenceInputStream(
    new FileInputStream(file1), 
    new SequenceInputStream(
     new ByteArrayInputStream("\n".getBytes()), // gives an endline between the provided files 
     new FileInputStream(file2))); 
+0

這會在這種情況下工作,但如果文件已經以換行符結束,這個解決方案會給你一個額外的空白行。 –

+0

好吧,額外的空白線不是那麼糟糕,我可以忍受它。 – Benedictus