Java: Как читать только int данные из текстового файла для выполнения расчетов?

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

  1. понедельник: 1 вторник: 2 среда: 3

...так далее

Когда есть новый ввод, он будет добавлен, поэтому обновленный текстовый файл выглядит так:

  1. понедельник: 1 вторник: 2 среда: 3
  2. понедельник: 4 вторник: 1 среда: 3
  3. понедельник: 6 вторник: 5 среда: 6
  4. понедельник: 7 вторник: 6 среда: 5

В основном я хочу сравнить новый вход с предыдущим. Как мне получить только все целые числа из последнего и последнего ввода?

или мне лучше использовать Excel?

Вот мой код:

try (
    InputStream fs = new FileInputStream("data.txt");
    // not sure how to use the Charset.forname
    InputStreamReader isr = new InputStreamReader(fs, Charset.forName("UTF-8"));
    BufferedReader br = new BufferedReader(isr)) {
    for (String line1 = br.readLine(); line1 != null; line = br.readLine()) {
        comp = line1 - line2; //line1 being current line(4) and line2 being the previous(3)
    }
}

2 ответа

Решение

Просто:

  1. Читайте ваш файл, сохраняя только 2 последние строки,
  2. Затем с помощью регулярного выражения извлеките целые числа.

Соответствующий код:

try (
    InputStream fs = new FileInputStream("data.txt");
    InputStreamReader isr = new InputStreamReader(fs, StandardCharsets.UTF_8);
    BufferedReader br = new BufferedReader(isr)) {
    // Previous line
    String prev = null;
    // Last line
    String last = null;
    String line;
    while ((line = br.readLine()) != null) {
        prev = last;
        last = line;
    }
    // Pattern used to extract the integers
    Pattern pattern = Pattern.compile("\\d+");
    // Matcher for the previous line
    Matcher matcher1 = pattern.matcher(prev);
    // Matcher for the last line
    Matcher matcher2 = pattern.matcher(last);
    // Iterate as long as we have a match in both lines
    while (matcher1.find() && matcher2.find()) {
        // Value of previous line
        int val1 = Integer.valueOf(matcher1.group());
        // Value of last line
        int val2 = Integer.valueOf(matcher2.group());
        // Do something here
    }
}

NB: Это предполагает, что у нас есть одинаковое количество целых чисел в обеих строках, иначе вы можете сравнить несвязанные значения.


Другой подход, если вы используете Java 8, вы можете использовать не целые числа в качестве разделителя, а затем полагаться на splitAsStream(CharSequence input) чтобы извлечь все ваши целые числа как List:

...
// Non integers as a separators
Pattern pattern = Pattern.compile("\\D+");
// List of extracted integers in previous line
List<Integer> previous = pattern.splitAsStream(prev)
    .filter(s -> !s.isEmpty())
    .map(Integer::valueOf)
    .collect(Collectors.toList());
// List of extracted integers in last line
List<Integer> current = pattern.splitAsStream(last)
    .filter(s -> !s.isEmpty())
    .map(Integer::valueOf)
    .collect(Collectors.toList());
// Do something here
  1. нужно быть немного более понятным в отношении кода вставки / извлечения, выполняется ли он тем же процессом / потоком. если ответ "да", я бы сохранял запрошенные данные в переменной, и таким образом вы экономите время, обращаясь к файлу и манипулируя его данными.

  2. в случае, если вставка выполняется другим процессом / потоком, вы должны быть осторожнее, поскольку существует гонка чтения / записи.

Другие вопросы по тегам