Чтение определенной строки из текстового файла с помощью Сканера - PullRequest
0 голосов
/ 12 июля 2020

Я читаю значения в текстовом файле одно за другим без проблем в Java. Файл имеет целочисленные значения, как показано ниже:

2 3 5 6 7 8 9 12 13 15 18 21 26 55 16 24 45 58 97

Мне нужно прочитать только значения одной строки вместо чтения всех значений, и есть пример Как получить номер строки с помощью сканера , но я ищу решение без использования LineNumberReader и использования счетчика путем зацикливания всех строк. Вместо этого было бы хорошо получить номер строки с помощью метода сканера, который я уже использую для чтения значений. Возможно ли это?

Вот метод, который я пытаюсь создать:

public static List<Integer> getInput(int lineIndex) throws FileNotFoundException{   
    List list = new ArrayList<Integer>();
    Scanner scan = new Scanner(new File(INPUT_FILE_NAME));
    int lineNum=0;
    //s = new Scanner(new BufferedReader(new FileReader("input.txt")));

    while(scan.hasNextLine()) {         
        if(lineNum == lineIndex) {
               list.add(scan.nextInt()); //but in this case I also loop all values in this line
        }
        lineNum++;      
    }
    scan.close();
    return list;
}

Ответы [ 2 ]

2 голосов
/ 12 июля 2020

Если у вас небольшой файл, в котором допустимо загружать все содержимое в память:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

....

public static List<Integer> getInput(int lineIndex) {
    List<Integer> list = new ArrayList<>();
    try {
        String line = Files.readAllLines(Paths.get("path to your file")).get(lineIndex);
        list = Pattern.compile("\\s+")
                .splitAsStream(line)
                .map(Integer::parseInt)
                .collect(Collectors.toList());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return list;
}

Метод Files.readAllLines возвращает список всех строк файла в виде строк, где каждая строка соответствует одной строке. с get(lineIndex) вы получите желаемую n-ю строку, и вам нужно только проанализировать строки до целых чисел.

Второй подход:

Если у вас большой файл, используйте ленивую оценку потоков :

public static List<Integer> getInputLargeFile(int lineIndex) {
    List<Integer> list = new ArrayList<>();
    try (Stream<String> lines = Files.lines(Paths.get("path to your file"))) {
        String line = lines.skip(lineIndex).findFirst().get();
        list = Pattern.compile("\\s+")
                .splitAsStream(line)
                .map(Integer::parseInt)
                .collect(Collectors.toList());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return list;
}

При таком подходе вы используете метод lines.skip для перехода на n строк с начала файла. А с findFirst().get() вы получаете следующую строку после прыжка. Затем сделайте то же, что и выше, чтобы преобразовать числа.

1 голос
/ 12 июля 2020

Чтобы не повторять при чтении числа в нужной строке, возможно, вы можете прочитать строку с помощью scanner.nextLine(), тогда вы можете использовать split("\\s"), чтобы получить начальные значения целых чисел в массив, затем вы можете просто привести и добавить их в вашем списке:

public static void main(String[] args) throws FileNotFoundException {
    Scanner scan = new Scanner(new File("input.txt"));
    List<Integer> list = new ArrayList<>();
    int lineNum = 0;
    int lineIndex = 2;

    while(scan.hasNextLine()) {
        if(lineNum == lineIndex) {
            String[] nums = scan.nextLine().split("\\s");
            for (String s : nums){
                list.add(Integer.parseInt(s));
            }
            break;
        }
        lineNum++;
        scan.nextLine();
    }

    System.out.println(list); // [12, 13, 15, 18, 21, 26, 55]
}
...