парсинг файла с помощью BufferedReader - PullRequest
0 голосов
/ 04 ноября 2019

Я хотел бы узнать больше о работе / разборе с файлами и, в более общем случае, со строками.

Итак, для этого я создал пользовательский файл .txt с таким вводом:

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

Я хочу проанализировать этот файл и собрать, сколько «функций» было активировано. Кроме того, я хочу агрегировать общее время, которое потребовалось для этого (т. Е. (0,32 + 0,4 + 1,34) / 0,6 = 2:46 минут)

Для приведенных выше данных вывод должен быть:

3 functions in total time of 2:46 minutes

Для решения, я, очевидно, создаю BufferedReader и анализирую построчно, но есть много пробелов, и я не очень хорош в работе с такого рода вводом. Я надеюсь, что кто-то может предложить мне правильный способ работы с такими данными.

Я также буду признателен за любую ссылку на упражнения такого рода, поскольку я пытаюсь найти работу, и они задают много вопросов о разборе данных такого типа (строк и файлов).

Спасибоза любую помощь! :)

Ответы [ 2 ]

1 голос
/ 04 ноября 2019

В общих чертах, вы должны обрабатывать файл построчно. Для каждой строки вы можете использовать функцию split, чтобы разбить строку на несколько частей (от String до String[]). Обратите внимание, что аргумент функции split является символом или регулярным выражением, используемым для разделения исходного текста. Например, использование str.split("\\s+") разделит входной текст, рассматривая несколько пробелов как один пробел. Кроме того, вы можете использовать функцию trim для удаления ненужных пробелов, конечных строк, вкладок и т. Д., А затем правильно анализировать информацию.

Что касается особенностей анализа значений времени, в Java есть несколько встроенных классов. и методы для обработки локальных дат, прошедшего времени и т. д. (например, LocalTime или Calendar). Однако в моем примере я создал собственный класс FuncTime, чтобы упростить задачу.

Вот код:

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
0 голосов
/ 04 ноября 2019

Вы имеете в виду что-то вроде этого?

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
...