使用 BufferedReader 解析文件

parsing a file with BufferedReader

我想详细了解 working/parsing 文件和字符串。

为此,我使用以下输入创建了一个自定义 .txt 文件:

Function            Time
print()             0:32
find()              0:40
insert()            1:34

我想解析该文件并汇总已激活的 "functions" 数量。另外,我想汇总为此花费的总时间(即(0.32+0.4+1.34)/0.6 = 2:46 分钟)

对于以上数据,输出应该是:

3 functions in total time of 2:46 minutes

对于解决方案,我显然创建了 BufferedReader 并逐行解析,但是有很多空格,而且我不太擅长处理这种输入。我希望是否有人可以建议我使用此类数据的正确方法。

我也会感谢任何 link 的此类练习,因为我正在努力找工作,他们会问很多关于解析此类数据(字符串和文件)的问题。

感谢您的帮助! :)

你的意思是这样的?

int count = 0;
int totalMinutes = 0;
int totalSeconds = 0;
try (BufferedReader in = Files.newBufferedReader(Paths.get("test.txt"))) {
    Pattern p = Pattern.compile("(\S+)\s+(\d+):(\d+)");
    for (String line; (line = in.readLine()) != null; ) {
        Matcher m = p.matcher(line);
        if (m.matches()) {
            // not used: String function = m.group(1);
            int minutes = Integer.parseInt(m.group(2));
            int seconds = Integer.parseInt(m.group(3));
            count++;
            totalMinutes += minutes;
            totalSeconds += seconds;
        }
    }
}
if (count == 0) {
    System.out.println("No functions found");
} else {
    totalMinutes += totalSeconds / 60;
    totalSeconds %= 60;
    System.out.printf("%d functions in total time of %d minutes %d seconds%n",
                      count, totalMinutes, totalSeconds);
}

输出

3 functions in total time of 2 minutes 46 seconds

一般来说,您应该逐行处理文件。对于每一行,您可以使用 split 函数将该行拆分为几个部分(从 StringString[])。请注意,split 函数的参数是用于拆分原始文本的字符或正则表达式。例如,使用 str.split("\s+") 会将输入文本拆分为多个 space 作为单个 space。此外,您可以使用 trim 功能删除不需要的 space 、结束行、制表符等,然后正确解析信息。

关于解析时间值的细节,Java 有几个内置的 classes 和方法来处理本地日期、经过的时间等(例如 LocalTimeCalendar)。但是,在我的示例中,我构建了一个自定义 FuncTime class 来简化操作。

代码如下:

package fileParser;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;


public class FileParser {

    private static class FuncTime {

        private int seconds;
        private int minutes;


        public FuncTime() {
            this.seconds = 0;
            this.minutes = 0;

        }

        public FuncTime(int seconds, int minutes) {
            this.seconds = seconds;
            this.minutes = minutes;
        }

        public void accumulate(FuncTime ft) {
            this.seconds += ft.seconds;
            while (this.seconds >= 60) {
                this.seconds -= 60;
                this.minutes += 1;
            }
            this.minutes += ft.minutes;
        }

        @Override
        public String toString() {
            return this.minutes + ":" + this.seconds;
        }
    }


    private static void parseInfo(String fileName) {
        // Create structure to store parsed data
        Map<String, FuncTime> data = new HashMap<>();

        // Parse data from file
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            // Skip header (DATA FILE MUST ALWAYS CONTAIN HEADER)
            String line = reader.readLine();
            // Begin to process from 2nd line
            line = reader.readLine();
            while (line != null) {
                // Split funcName and time
                String[] lineInfo = line.split("\s+");
                String funcName = lineInfo[0].trim();
                // Split time in minutes and seconds
                String[] timeInfo = lineInfo[1].split(":");
                int seconds = Integer.valueOf(timeInfo[1].trim());
                int minutes = Integer.valueOf(timeInfo[0].trim());

                // Store the function name and its times
                FuncTime ft = new FuncTime(seconds, minutes);
                data.put(funcName, ft);

                // Read next line
                line = reader.readLine();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        // Print parsed information
        FuncTime totalTime = new FuncTime();
        for (Entry<String, FuncTime> entry : data.entrySet()) {
            String funcName = entry.getKey();
            FuncTime ft = entry.getValue();
            System.out.println(funcName + " " + ft);
            totalTime.accumulate(ft);
        }
        // Print total
        System.out.println(data.size() + " functions in total time of " + totalTime);
    }

    public static void main(String[] args) {
        String fileName = args[0];

        parseInfo(fileName);
    }

}

您可以将提供的示例数据存储在名为 example.data:

的文件中
$ more example.data
Function            Time
print()             0:32
find()              0:40
insert()            1:34

和运行以上代码获得以下输出:

insert() 1:34
print() 0:32
find() 0:40
3 functions in total time of 2:46