Блок кода не трогается

Я создаю небольшое приложение на Java, небольшую игровую механику, но ничего серьезного. У меня есть класс, целью которого является получение данных из файла. Но когда я объявляю два класса для чтения из него, программа просто игнорирует все и продолжает работу. В результате, когда я пытаюсь получить доступ к соответствующим спискам, я получаю исключение с нулевым указателем. Код метода, который извлекает данные, ниже:

public void getData(int l, player tmp, level le) {
        String[] dataPlayer;
        String[] dataLevel;

        try {
            //FileReader f = new FileReader(this.levelPath.concat(Integer.toString(l)));
            File f = new File(this.levelPath.concat(Integer.toString(l)));
            BufferedReader buff = new BufferedReader(new FileReader(f));
            System.out.println("Reached");

            boolean eof = false;
            while (!eof) {
                String b = buff.readLine();

                if (b == null)
                    eof = true;
                else {
                    if (b.contains("player")) {
                        dataPlayer = b.split("-");
                        for (int i = 0; i < dataPlayer.length; i++) {
                            if (i == 0)
                                continue;

                            items it = new items(dataPlayer[i]);
                            tmp.setInventory1(it);
                        }
                    }else if (b.contains("level")) {
                        dataLevel = b.split("-");
                        for (int i = 0; i < dataLevel.length; i++) {
                            if (i == 0)
                                continue;

                            items it = new items(dataLevel[i]);
                            le.setSpecific(it);
                        }
                    }
                }
            }
        }catch (IOException i) {
            i.getMessage();
        }


    }

Содержимое файла "levelData1":

player-hat
player-flashlight
level-flower
level-rock
player-adz

Проблема с этой конкретной проблемой заключалась в пути, ему нужен был абсолют вроде этого / home / toomlg4u / IdeaProjects / javaProject / src / Data / levelData.

Я предполагаю, что buff имеет значение null, вычисление имени файла кажется немного сложным. Или файл пуст.

NiVeR 23.06.2018 00:01

@NiVeR Мне это нужно, потому что у меня есть 3 файла для 3 уровней и атрибут с именем levelpath, который равен «levelData», поэтому я объединяю аргумент l, который представляет собой число, которое пользователь дает, например, 1,2,3 (уровни), поэтому я открываю соответствующий файл для чтения. Но реально озадачен этим ...

Marios Koni 23.06.2018 00:06

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

NiVeR 23.06.2018 00:08

Я пробовал это, он никогда не опускается ниже класса bufferedReader

Marios Koni 23.06.2018 00:19

Тогда у вас должно быть какое-то исключение, вы что-то видите?

NiVeR 23.06.2018 00:27

Я должен добавить, потому что ничего не вижу. Я попробую это.

Marios Koni 23.06.2018 00:27

1) }catch (IOException i) { i.getMessage(); } Не уверен, что вы ожидать, чтобы произойти в этом коде, но ничего полезного будут не происходит. Измените его на }catch (IOException i) { i.printStackTrace(); } 2) Для более быстрого получения помощи отправьте минимальный воспроизводимый пример или Краткий, автономный, правильный пример.

Andrew Thompson 23.06.2018 03:34

@AndrewThompson Это помогло мне и доказало, что файл не существует, по крайней мере, согласно программе.

Marios Koni 23.06.2018 11:44

Прохладный. Да, трассировки стека могут быть очень информативными. Теперь, возможно, замените File f = new File(this.levelPath.concat(Integer.toString(l))); на File f = new File(this.levelPath.concat(Integer.toString(l))); System.out.println(f.getAbsolutPath());. Убедитесь, что он указывает на то, куда указывает считать.

Andrew Thompson 23.06.2018 12:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
9
75
3

Ответы 3

Вы делаете много вещей внутри этого метода try / catch, которые могут не вызывать исключения IOException. Если вы получите другое исключение, его не поймают. В зависимости от того, какая другая обработка исключений у вас есть, это может вызвать странное поведение. Для отладки вы можете перехватить все исключения и посмотреть, получаете ли вы что-нибудь еще.

Теперь я убежден, что проблема в объекте BufferReader, после чего код не трогается.

Marios Koni 23.06.2018 00:27

Хорошо, теперь убеди меня в этом. =] В этой ситуации я всегда рекомендую сократить код до максимально простого, в том числе вырезать все ПОСЛЕ, когда вы думаете, что может произойти ошибка. Для вашего примера, поскольку есть код, который не достигается, избавьтесь от этого кода (закомментируйте его, создайте новый проект только с тем кодом, который, как вы знаете, работает, что угодно. Не выполняйте никаких вложенных вызовов функций, по одной операции на Установите точку останова перед тем местом, где, по вашему мнению, возникла ошибка, и переходите через код, проверяя все по ходу. Это должно указать вам на проблему.

Jon E 25.06.2018 00:06

Вот так должна выглядеть достойная программа на Java:

private Stream<Items> asStreamOfItems(String line){
    return Stream.of(line.split("-")).skip(1).map(Items::new);
}

public void parseFile(String pathToTheFile) throws IOException {
    List<String> lines = Files.readAllLines(Paths.get(pathToTheFile));
    List<Items> players = lines.stream().filter(line -> line.contains("player")).flatMap(this::asStreamOfItems).collect(Collectors.toList());
    List<Items> levels = lines.stream().filter(line -> line.contains("level")).flatMap(this::asStreamOfItems).collect(Collectors.toList());
    ........
}

В этом случае все ваши странные ошибки исчезнут.


После того, как вы отредактировали сообщение, я увидел содержимое вашего файла. В этом случае код должен выглядеть так:

class Items {
    private final String name;

    public Items(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public static Items parse(String line) {
        return new Items(line.split("-")[1]);
    }

}

public void parseFile(String pathToTheFile) throws IOException {
    List<String> lines = Files.readAllLines(Paths.get(pathToTheFile));
    List<Items> players = lines.stream().filter(line -> line.contains("player")).map(Items::parse).collect(Collectors.toList());
    List<Items> levels = lines.stream().filter(line -> line.contains("level")).map(Items::parse).collect(Collectors.toList());
    ..............
}

Кстати, вы нарушили много правил Java и общих правил программирования, таких как:

  1. использование continue - плохая практика. Его следует использовать только в крайних случаях, потому что это затрудняет чтение кода.
  2. имя класса в Java должно быть в нотации CamelCase
  3. один метод должен иметь только одну ответственность
  4. НЕ изменяйте объект внутри метода (пример: tmp.setInventory1(it);) очень-очень-очень плохая практика
  5. когда вы работаете с потоками, используйте try with resource или try / catch / finally, чтобы закрыть поток после завершения чтения.
  6. Прежде чем приступить к написанию кода, изучите JAVA IO SDK, чтобы найти более эффективные методы чтения из файлов.

«Вот как делается настоящий дом. Так что снести свой, потому что он старый и уродливый, кого волнует, есть ли у вас ресурсы».

NiVeR 23.06.2018 00:37

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

Marios Koni 23.06.2018 00:53

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

NiVeR 23.06.2018 00:53

Если вы хотите остаться в коде цикла, вы можете реорганизовать свой код, чтобы он выглядел так:

public void getData(int l, player tmp, level le) {
    try (BufferedReader buff = new BufferedReader(new FileReader(new File(this.levelPath + l)))) {
        String b;
        while ((b = buff.readLine()) != null) {
            if (b.contains("player")) {
                String[] dataPlayer = b.split("-");
                items it = new items(dataPlayer[1]); //because you know that you will have an array with only 2 elements
                tmp.setInventory1(it);
            }else if (b.contains("level")) {
                String[] dataLevel = b.split("-");
                items it = new items(dataLevel[1]); //because you know that you will have an array with only 2 elements
                le.setSpecific(it);
            }
        }
    }catch (IOException e) {
        e.printStackTrace();
    }
}

Он немного лучше, чем у вас, его легче отлаживать и читать. Советую прочитать про попробуйте с ресурсами.

Как правило, каждый раз, когда вы открываете поток, вы должны его закрывать. Если вы не открываете его сами, не закрывайте его.

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

Marios Koni 23.06.2018 12:00

как начать проект?

Octavian R. 23.06.2018 12:05

Я снова изменил путь, и это сработало. НО, снова остановившись в строке, я передаю новый элемент (его) в свой tmp.setInventory1. С исключением нулевого указателя.

Marios Koni 23.06.2018 12:07

Вы можете использовать эту строку, например: try (BufferedReader buff = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/game.txt"‌​)))), и в этом случае файл game.txt должен быть помещен в путь к классу. Если у вас все еще есть NPE, опубликуйте содержимое класса player, чтобы я мог видеть содержимое метода setInventory1.

Octavian R. 23.06.2018 12:12

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