所以我能够读出这样的现有文件:
File file = new File("C:\\Something/test.txt");
FileInputStream fis = new FileInputStream(file);
BufferedReader bfr = new BufferedReader(new InputStreamReader(fis));
现在我可以使用bfr.readLine()并逐行读取。 如果我想读出另一个文件,我是否必须创建一个新的BufferedReader,或者有没有办法用一个BufferedReader读出多个文件?
答案 0 :(得分:2)
您可以使用SequenceInputStream
按顺序读取文件。
File file1 = new File("C:\\Something/test1.txt");
File file2 = new File("C:\\Something/test2.txt");
FileInputStream fis1 = new FileInputStream(file1);
FileInputStream fis2 = new FileInputStream(file2);
SequenceInputStream is = new SequenceInputStream(fis1, fis2);
BufferedReader bfr = new BufferedReader(new InputStreamReader(is));
要关闭这两个流(和阅读器),只需使用try-with-resources
:
try (
FileInputStream fis1 = new FileInputStream(file1);
FileInputStream fis2 = new FileInputStream(file2);
SequenceInputStream is = new SequenceInputStream(fis1, fis2);
BufferedReader bfr = new BufferedReader(new InputStreamReader(is))
) {
System.out.println(bfr.readLine());
System.out.println(bfr.readLine());
}
如果有两个以上的流,我们必须使用接受Enumeration
个InputStream
的构造函数。正如@Boris the Spider所提到的,这里棘手的部分正在关闭所有流。我们可以创建一个Autoclosable
来包含要关闭的所有InputStream
,但是在构造该容器之前,但是在构建了一些流之后,可能会发生异常,所以有些流将保持未公开状态。
一种干净的方法是在try-with-resources
语句中明确包含所有流:
try (
FileInputStream fis1 = new FileInputStream(file1);
FileInputStream fis2 = new FileInputStream(file2);
FileInputStream fis3 = new FileInputStream(file3);
...
SequenceInputStream is = new SequenceInputStream(new IteratorEnumeration<>(Arrays.asList(fis1, fis2, fis3, ...).iterator()));
BufferedReader bfr = new BufferedReader(new InputStreamReader(is))
) {
// .. read from bfr
}
IteratorEnumeration
是https://stackoverflow.com/a/7086010/7637120
另一种选择是手动跟踪已成功打开的输入流列表,如果下一个流的构造失败则关闭它们。
public class InputStreams implements AutoCloseable {
private final List<InputStream> streams = new ArrayList<>();
public List<InputStream> getStreams() {
return streams;
}
public void add(InputStream is) {
streams.add(is);
}
@Override
public void close() throws IOException {
IOException firstException = null;
for (InputStream stream : streams) {
try {
stream.close();
} catch (IOException e) {
if (firstException == null) {
firstException = e;
} else {
firstException.addSuppressed(e);
}
}
}
if (firstException != null) {
throw firstException;
}
}
}
InputStreams streams = new InputStreams();
while (moreStreams()) {
InputStream nextStream = null;
try {
nextStream = getNextStream();
streams.add(nextStream);
} catch (IOException e) {
// the following will close nextStream and all the earlier streams
try (InputStreams streamsToClose = streams) {
if (nextStream != null) {
nextStream.close();
}
} finally {
throw e;
}
}
}
try (
InputStreams streamsToClose = streams;
SequenceInputStream is = new SequenceInputStream(new IteratorEnumeration<>(streams.getStreams().iterator()));
BufferedReader bfr = new BufferedReader(new InputStreamReader(is))
) {
// work with bfr...
}