提问人:toy 提问时间:10/11/2023 最后编辑:toy 更新时间:10/11/2023 访问量:66
为什么在 BufferedReader 期间检查每行 isEmpty 对 Java 逐行读取文件会有所不同
Why checking isEmpty each row during BufferedReader makes a difference in Java reading file line by line
问:
我有一段代码正在读取一个文件。文件的内容只是每行的一个 ID。没什么特别的。但是,我不确定为什么此代码的每种样式都会产生不同的结果。
文件的内容如下所示
a9c536f6-592f-4458-b61b-6ed3f875e990
d6b384d3-8fae-2dd3-ed06-b57cb65b093c
31474dd6-5c3b-4dc4-82cb-7e05121a77e1
b37dd457-da49-4972-9e3d-cd642e975562
f88df909-35bc-453c-b706-d48b5a11af9a
5d75083b-c4a8-4ad1-8494-645aaabfb283
85d8170e-8982-43c2-b574-9d7fe96d1b46
68bf33d0-1b5e-480c-83f2-ae38d9e0c8c8
26ea9d4a-f509-43b2-850f-cc445dccfd33
f9e9bd88-f67d-4e66-b281-eceeb57985eb
@Test
void testReadFile() throws Exception
{
String fileName = "/Users/user/Downloads/payload";
// #1
BufferedReader reader = new BufferedReader(new FileReader(fileName));
Set<String> readUsingCollect = reader.lines().filter(l -> !l.isEmpty()).collect(Collectors.toSet());
reader = new BufferedReader(new FileReader(fileName));
String row;
// #2
Set<String> readUsingNonEmpty = new HashSet<>();
while ((row = reader.readLine()) != null && !row.isEmpty()) {
readUsingNonEmpty.add(row);
}
reader = new BufferedReader(new FileReader(fileName));
// #3
String row1;
Set<String> readNonCheckingNonEmpty = new HashSet<>();
int counter = 0;
while ((row1 = reader.readLine()) != null) {
if (row1.isEmpty()) {
counter += 1;
}
readNonCheckingNonEmpty.add(row1);
}
Sets.SetView<String> difference = Sets.difference(readNonCheckingNonEmpty, readUsingNonEmpty);
System.out.println("Size readUsingCollect: " + readUsingCollect.size());
System.out.println("Size readUsingNonEmpty: " + readUsingNonEmpty.size());
System.out.println("Size readNonCheckingNonEmpty: " + readNonCheckingNonEmpty.size());
System.out.println("Counter: " + counter);
System.out.println("Difference in size: " + difference.size());
reader.close();
}
下面是运行上述代码的结果
Size readUsingCollect: 7525
Size readUsingNonEmpty: 5498
Size readNonCheckingNonEmpty: 7526
Counter: 2
Difference in size: 2028
我想知道为什么 #2 产生的结果与 #3 和 #1 不同。文件的内容没有空行。最让我困惑的是,我希望 #1 和 #2 是相同的,但它们是不同的。
答:
1赞
Thomas Kläger
10/11/2023
#1
正如@Cwift评论中提到的:
方法 #2 的问题在于
while ((row = reader.readLine()) != null && !row.isEmpty()) {}
不过滤空行 - 它会在第一个空行处终止循环。
如果要读取整个文件并过滤掉空行,则需要将方法#2实现为:
Set<String> readUsingNonEmpty = new HashSet<>();
while (row = reader.readLine()) {
if (!row.isEmpty()) {
readUsingNonEmpty.add(row);
}
}
评论
0赞
Cwift
10/11/2023
谢谢你为我发布它。我仍然想知道为什么 #1 与 #3 不同。
1赞
Thomas Kläger
10/11/2023
@Cwift井 #1 过滤掉空行 (),#3 计算空行,但无论如何都将它们添加到结果集中。由于空字符串被认为是相等的,因此结果集中最多只能有一个空字符串,这就是为什么 #3 在结果集中还有一个条目的原因。.filter(l -> !l.isEmpty())
评论
readUsingCollect
readNonCheckingNonEmpty
while ((row = reader.readLine()) != null && !row.isEmpty())
如果该行不为 null 且为空,则中断