【问题标题】:Parsing file using indexOf() method in Java在 Java 中使用 indexOf() 方法解析文件
【发布时间】:2012-09-10 16:01:36
【问题描述】:

在stackoverflow 中验证this post 后,我使用indexOf() 方法来解析文件中的值。以下是我的文件格式-

10/05/2005 10:02;AM;a@xyz.com;student=student1 std=X marks=87 rollnumber=102
10/05/2005 10:05;AM;b@xyz.com;student=student2 std=IX rollnumber=26
10/05/2005 10:15;PM;c@xyz.com;student=student3 std=VII marks=87 attandance=5 rollnumber=12
10/05/2005 10:32;AM;d@xyz.com;student=student4 std=V marks=87 rollnumber=69

注意:电子邮件中的domain namexyz.com 不会在任何地方更改。
下面是我目前使用的代码 sn-p-

            FileInputStream fis = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    fis));

            String line = "";
            while ((line = br.readLine()) != null) {

                int index = -1;

                if ((index = line.indexOf("xyz.com")) != -1) {
                    int inStudent = line.indexOf("student=", index);
                    int spaceExistsinStudent = -1;
                    int studentIndex = -1;

                    if ((spaceExistsinStudent = line.indexOf("student=\"", inStudent)) != -1)
                        studentIndex = line.indexOf(" ", inStudent);
                    else
                        studentIndex = line.indexOf("\" ", spaceExistsinStudent);

                    int inSTD = line.indexOf("std=", studentIndex);
                    int spaceExistsinSTD = -1;
                    int stdIndex = -1;

                    if ((spaceExistsinSTD = line.indexOf("std=\"", inSTD)) != -1)
                        stdIndex = line.indexOf(" ", inSTD);
                    else
                        stdIndex = line.indexOf("\" ", spaceExistsinSTD);

                    String studentName = line.substring(inStudent + 9, studentIndex);
                    String stdName = line.substring(inSTD + 4, stdIndex);

没有必要粘贴整个代码。
好吧,使用上面的实现,我可以工作,但是考虑到性能,这个有效的解决方案吗?实现相同目标的任何更好方法....
提前谢谢您。

【问题讨论】:

  • 即使域名在您估计的未来不会发生变化,您也应该编写代码,不要将其嵌入到逻辑中间的固定字符串中。至少让它成为一个成员变量,这样以后就可以在不浪费大量精力的情况下对其进行更改。或者更好的是,将其作为方法的参数,然后伪造配置子系统,直到稍后(当你确实需要它时)。
  • 是的,我会记住的......

标签: java string performance parsing indexof


【解决方案1】:

我建议使用 StringTokenizer,而不是 indexOf()。基本上你可以根据一些分隔符分割你的字符串(例如:;)..

while 循环中的示例

        StringTokenizer st = new StringTokenizer(line,";");


        st.nextToken(); //Date
        st.nextToken(); //AM
        String email = st.nextToken();
        String values = st.nextToken();

        StringTokenizer st2 = new StringTokenizer(values," ");


        while (st2.hasMoreElements()) {
            String token = (String) st2.nextElement();
            if(token.startsWith("student=")){
                System.out.println(token.substring("student=".length()));
            }else if(token.startsWith("std=")){
                System.out.println(token.substring("std=".length()));
            }

        }

【讨论】:

  • 你似乎是对的。但是目前我只担心性能。您如何看待执行时间方面的实施?
  • 性能瓶颈几乎肯定不是解析代码——而是磁盘IO。但是是的,StringTokenizer 很快,理论上这个实现应该比使用 indexOf 更快,因为它只扫描输入行一次。
  • @JoeK:让我在我的机器上运行两个版本并触发执行时间
  • @JoeK:可悲的是,StringTokenizer 花费的时间是indexOf 的 1.5 倍。我选择indeOf 的原因只是因为它比StringTokenizer 性能更好,正如我之前在我的问题中所说的那样。
【解决方案2】:

您不需要对所有内容都使用 indexOf。如果您想查看一个字符,可以使用 charAt() 例如你在哪里检查'"'

我会使用一种提取字段值的方法来简化代码。

【讨论】:

  • 你能告诉我更详细的吗?
【解决方案3】:

正如我在之前的评论中所说,我很惊讶解析是这里的瓶颈。但是,如果您想知道其他可以做到这一点的方法,并尝试一下,看看哪种方法最快,这里还有两个尚未发布的想法 - 使用 .split

String[] arr1 = line.split(";");
String dateTime = arr1[0];
String ampm = arr1[1];
String email = arr1[2];
String[] arr2 = arr1[3].split(" ");
String student, std, marks, rollnumber;
student = std = marks = rollnumber = null;
for (String str : arr2) {
    String value = str.substring(str.indexOf("=") + 1);
    switch(str.charAt(2)) {
    case 'u': student = value; break;
    case 'd': std = value; break;
    case 'r': marks = value; break;
    case 'l': rollnumber = value; break;
    }
}

或者使用正则表达式:

private static final Pattern PATTERN = Pattern.compile("([^;]+);([^;]+);([^;]+);student=([^ ]+) std=([^ ]+) marks=([^ ]+) rollnumber=([^ ]+)");

Matcher m = PATTERN.matcher(line);
m.find();
String dateTime = m.group(1);
String ampm = m.group(2);
String email = m.group(3);
String student = m.group(4);
String std = m.group(5);
String marks = m.group(6);
String rollnumber = m.group(7);

【讨论】:

  • Check this.. 在开始我的开发之前我参考了这个链接。过程。
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多