这里的代码示例是用Java编写的,但是我在C++中遇到了这个问题,基本上在任何需要解析这样一个文件的地方都遇到了这个问题。我正在分析来自电子设计自动化软件套件的文件中的字符串。该文件被称为"netlist",它包含有关电子设备以及特殊字符串的信息。以下是一个示例:
R3 1 4 137 425 1
R4 1 2 60 479 0
R5 2 3 55 596 0
V2 3 4 171 680 1
.end我有一个名为Device的Java类,它接收文件的一行并将数据输入到每个设备的成员变量中(例如,顶层是一个名为R3的电阻,连接到节点1和4等)。当我进入来自EDA软件的.end字符串时,显然无法将它解析为设备。
我觉得我一遍又一遍地重写相同的代码,这对我来说就像是一种严重的反模式。我使用一个while循环来读取每一行,检查它是否不是".end“字符串,然后再次检查它作为离开循环的条件:
String line = "";
BufferedReader in;
in = new BufferedReader(new FileReader(fileName));
while(line != null && !line.startsWith(".end"))
{
line = in.readLine();
//this feels like an anti-pattern...
if(!line.startsWith("end"))
{
Device d = new Device();
d.parseDeviceData(line);
devices.add(d); //devices is an ArrayList
}
}是那张双重支票让我心烦。我能想到的唯一方法就是在while循环之外读取第一行,然后在循环结束时读取每一行,但这并不能真正解决我的问题。为什么我应该有两个readLine语句?
所以,我认为这是反模式是对的吗?如果是的话,我该如何避免呢?
发布于 2017-08-04 13:34:42
基本上,您希望按行读取文件,如果到达末尾或出现以.end开头的行,则停止。您的当前方法确实可以简化,因为第二次检查的结果已经知道。
我会这样做:
BufferedReader in;
in = new BufferedReader(new FileReader(fileName));
while (true) {
String line = in.readLine();
if (line == null || line.startsWith(".end")) {
// Abort parsing the file
break;
}
// Valid line, parse it
Device d = new Device();
d.parseDeviceData(line);
devices.add(d);
}如果您不喜欢while (true),那么还可以在变量中保存比较结果。
请注意,我们现在应该使用名为NIO的Javas新I/O库。它更健壮,更容易使用,而且提供更多。它的主要类是Files和Paths。特别令人感兴趣的是Files#readAllLines和Files#lines,第一个返回一个保存文件完整内容的List<String>,第二个返回一个Stream<String>,在那里您可以展示Lambda表达式的全部功能。
注意,目前,这两种方法都不是实现“读到”的最佳选项,因为第一种方法将读取整个内容,Stream的操作也不容易中止。因此,Java 9将引入方法Stream#takeWhile和Stream#dropWhile。
但是,可以很容易地将Stream转换为Iterator,并且可以再次使用常规逻辑,因此我们可以使用以下代码:
Iterator<String> lineIterator = Files.lines(Paths.get(fileName)).iterator();
while (lineIterator.hasNext()) {
String line = lineIterator.next();
if (line.startsWith(".end")) {
// Abort parsing the file
break;
}
// Valid line, parse it
Device d = new Device();
d.parseDeviceData(line);
devices.add(d);
}发布于 2017-08-04 13:08:02
您可以将行扫描位放入while条件:
while(!(line = in.readLine()).startsWith(".end"))
{
System.out.println(line);
}它不好看,但它将防止你不得不测试你的情况两次。它会变得更脏(真的很脏!)如果你有很多条件要检查的话。
发布于 2017-08-04 13:37:47
也许我错了,但答案似乎非常简单
String line = null;
BufferedReader in;
in = new BufferedReader(new FileReader(fileName));
for(;;)
// instead use while(true) on personal taste / teacher / tradition / :)
{
line = in.readLine();
if(line == null)
{
// break because of eof, wrong end, do something !!!!
// throw new XxxxxxxxException("bad end of file")
break;
}
if( line.startsWith(".end") )
{
// correnct end
break;
}
Device d = new Device();
d.parseDeviceData(line);
devices.add(d); //devices is an ArrayList
}https://stackoverflow.com/questions/45507297
复制相似问题