Case выполняется только один раз
Пытаюсь в джаву. Пытаюсь сделать простой консольный каталог, делаю пункты главного меню, которые можно выбрать, если ввести цифры 1, 2, 3. При выборе пункта содержимое текстового файла выводится на экран. Возникла такая проблема: можно выбрать пункт только один раз, после чего нет никакой реакции на последующий ввод цифр. Данные с консоли считываю с помощью BufferedReader. Сам выбор пунктов делаю с помощью switch-case (с if-else результат тот же). Надеюсю, что нормально описал суть проблемы.
Main.java
package filework;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in,"Cp1251"));
readFile r = new readFile();
Menu.menu(args);
}
}
Menu.java
package filework;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Menu {
public static void menu(String[] args) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in,"Cp1251"));
readFile r = new readFile();
String menu_text = "========== Catalog ==========="
+ System.lineSeparator() + ""
+ System.lineSeparator() + "1: About catalog"
+ System.lineSeparator() + "2: Tile-entity"
+ System.lineSeparator() + "3: Tile-entity list"
+ System.lineSeparator() + "'exit'"
+ System.lineSeparator() + "===============================================";
System.out.println(menu_text);
String data;
String path;
data=in.readLine();
switch (data) {
case ("1"):
path = "D:\\Study\\java\\Test\\Assets\\About Catalog.txt";
r.printFile(path);
break;
case ("2"):
path = "D:\\Study\\java\\Test\\Assets\\About Block-Tileentity.txt";
r.printFile(path);
break;
case ("3"):
path = "D:\\Study\\java\\Test\\Assets\\About Block-Tileentity.txt";
r.printFile(path);
default:
}
while(!data.equals("exit"))
{
data=in.readLine();
}
}
}
FileRader.java
package filework;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class readFile {
private BufferedReader in;
/**
* метод выводит содержимое файла на экран
*/
public void printFile(String filepath){
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(filepath),"utf-8"));
System.out.println("============================");
String s = in.readLine();
System.out.println(s);
System.out.println("============================");
in.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
Ответы (3 шт):
Слишком сложно. Если у вас есть много классов, то это еще не означает, что ваш код превратился в ООП. Вы просто разбили процедурный код на множество классов. ООП проявляется в полиморфизме, а полиморфизм невозможен без наследования. Посему давайте немного упростим:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class FileReader {
private final static String DOC_SEPARATOR = "============================";
private final static String MENU_TEXT = "========== Catalog ==========="
+ System.lineSeparator() + ""
+ System.lineSeparator() + "1: About catalog"
+ System.lineSeparator() + "2: Tile-entity"
+ System.lineSeparator() + "3: Tile-entity list"
+ System.lineSeparator() + "'exit'"
+ System.lineSeparator() + "===============================================";
public static void main(String[] args) throws IOException {
try (Scanner scanner = new Scanner(System.in)) {
break_point:while (true) {
System.out.println(MENU_TEXT);
switch (scanner.nextLine()) {
case ("1"):
printFile("D:\\Study\\java\\Test\\Assets\\About Catalog.txt");
break;
case ("2"):
printFile("D:\\Study\\java\\Test\\Assets\\About Block-Tileentity.txt");
break;
case ("3"):
printFile("D:\\Study\\java\\Test\\Assets\\About Block-Tileentity.txt");
break;
case ("exit"):
break break_point;
}
}
}
}
private static void printFile(String filepath) throws IOException {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), "utf-8"))) {
System.out.println(DOC_SEPARATOR);
in.lines().forEach(System.out::println);
System.out.println(DOC_SEPARATOR);
}
}
}
Мсье сверху с 7,5 тысяч рейтинга и серебренным значком за джаву знает толк в извращениях. Такому кодстайлу придерживаться новичку крайне не советую, чистое ИМХО.
А теперь по пунктам, почему я, собственно, тут развонялся:
- Неправильный порядок модификаторов. Согласно спецификации сначала
staticпотомfinal. Как бы мелочь, но все-таки спецификации языков существуют неспроста. - В методе
printFile()используется монструозных размеров синтаксическая конструкция для чтения файла. Хотя до этого вmainавтор использовалScanner, который бы с этой задачей прекрасно бы справился.
Scanner scanner = new Scanner(new File(filepath);
- Goto. goto? goto. Хорошо, когда есть неисчисляемое количество вложенных циклов
breakс меткой необходим. Но не здесь же. Да и зачем? Вроде как exit подразумевает выход из программы. System.lineSeparator()почему бы не заменить на\n?case "2"и "3" идентичен.- Почему бы не вынести путь к файлам в константу? А как же DRY?
Дабы не быть голословным прикладываю свой говнокодец:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FileReader {
private static final String DOC_SEPARATOR = "============================";
private static final String MENU_TEXT = "========== Catalog ===========\n\n"
+ "1: About catalog\n"
+ "2: Tile-entity\n"
+ "3: Tile-entity list\n"
+ "'exit'\n"
+ "===============================================\n";
private static final String ROOT_DIR = "D:\\Study\\java\\Test\\Assets\\";
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
while (true) {
System.out.println(MENU_TEXT);
System.out.print(">>> ");
String input = scanner.nextLine();
switch (input) {
case "1":
printFile(ROOT_DIR + "About Catalog.txt");
break;
case "2":
case "3":
printFile(ROOT_DIR + "About Block-Tileentity.txt");
break;
case "exit":
System.exit(0);
break;
default:
System.out.println("Unknown command");
break;
}
}
}
}
private static void printFile(String filepath) {
try (Scanner scanner = new Scanner(new File(filepath))) {
System.out.println(DOC_SEPARATOR);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
System.out.println(DOC_SEPARATOR);
} catch (FileNotFoundException e) {
System.out.println("File not found\n");
}
}
}
P.S
К автору вопроса претензий у меня нет и быть не может. Все вопросы адресованы исключительно к системному архитектору предыдущего ответа. Автору желаю успехов в обучении сию ремеслу и высокооплачиваемого трудоустройства!
Так у вас же switch вне цикла. Вы сначала 1 раз читаете строку ввода, выполняете switch-case, а затем в этих строках:
while(!data.equals("exit"))
{
data=in.readLine();
}
просто в цикле читаете данные с клавиатуры, не вызывая case. Как вариант - можно вынести switch-case в отдельный метод, и вызывать его в цикле чтения данных, примерно так:
while(!data.equals("exit"))
{
data=in.readLine();
proccessInput(data);
}
Вообще - код конечно требует серьезного рефакторинга, но это сильно выходит за рамки обсуждаемого вопроса:)