Java关闭Scanner会引发异常吗?

huangapple go评论97阅读模式
英文:

java closing scanner causes exceptions?

问题

我正在制作一个程序,将文本文件中的指令转换为绘图。该文件包含命令和参数,例如 "CIRCLE 100 200 15"。一旦扫描器遇到一行写着 "END" 的指令,我需要关闭扫描器,停止读取文件并停止绘图。但是当我在 "END" 的 switch case 中使用 'obj.close()' 时,我会收到 InvocationTargetException、RuntimeException 和 IllegalStateException。我尝试过查找解决方案,但在我的情况下找不到有效的解决方法。我尝试过将扫描器设置为静态变量,但会出现错误消息 "modifier static not allowed here",将其放入 try 语句中,将其移出 try 语句,但都没有效果。以下是代码部分:

public class Graphic extends Application {
    // ... 其他代码 ...

    public void start(Stage stage) {
        // ... 其他代码 ...

        Group root = new Group();  //创建一个组来容纳所有形状
        try {
            Scanner obj = new Scanner(new File("star.txt"));  //读取文本文件
            while(obj.hasNextLine()){
                String[] strArray = obj.nextLine().split(" ");  //将每个命令拆分到新行
                switch(strArray[0]){
                    case "SIZE":                                      //设置窗口大小
                        // ... 处理SIZE命令 ...
                    case "LINE":                                      //绘制线段
                        // ... 处理LINE命令 ...
                    case "CIRCLE":                                    //绘制圆形
                        // ... 处理CIRCLE命令 ...
                    case "RECTANGLE":                                 //绘制矩形
                        // ... 处理RECTANGLE命令 ...
                    case "TEXT":                                      //绘制文本
                        // ... 处理TEXT命令 ...
                    case "//":                                        //忽略注释
                        // ... 处理注释 ...
                    case "END":                                       //停止读取文件
                        obj.close();
                        break;
                }
            }

            Scene scene = new Scene(root, fwidth, fheight, Color.BLACK);
            stage.setTitle("poop");
            stage.setScene(scene);
            stage.show();
        }
        catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        }
    }

    // ... 其他代码 ...

    public static void main(String[] args) {
        launch(args);
    }
}

错误信息如下:

Exception in Application start method
java.lang.reflect.InvocationTargetException
// ... 错误信息 ...
Caused by: java.lang.IllegalStateException: Scanner closed
// ... 错误信息 ...
Exception running application sample.Graphic

我不确定是否存在简单的解决方法,我是否遗漏了什么,如果有人能够帮助,我将不胜感激。

英文:

i'm making a program that converts instructions from a text file into a drawing. the file contains commands and arguments, like "CIRCLE 100 200 15". once the scanner hits a line that says "END" i need to close the scanner, stop reading the file, and stop drawing. but when i use 'obj.close()' in the END switch case, i get InvocationTargetException, RuntimeException, and IllegalStateException. i've tried to look up solutions but i can't find any that work in my case. i've tried making the scanner static, which causes an error saying "modifier static not allowed here", making it into a try statement, moving it outside the try statement, and nothing works. here's the code:

public class Graphic extends Application {
/**
* The start method. Required by Application
*
* @param stage
*/
public void start(Stage stage) {
double fwidth = 0;
double fheight = 0;
...
Group root = new Group();  //creates group for all shapes to go in
try {
Scanner obj = new Scanner(new File("star.txt"));  //reads text file
while(obj.hasNextLine()){
String[] strArray = obj.nextLine().split(" ");  //splits all commands to new line
switch(strArray[0]){
case "SIZE":                                      //sets size of window
...
case "LINE":                                      //creates each line
...
case "CIRCLE":                                    //creates each circle
...
case "RECTANGLE":                                 //creates each rectangle
...
case "TEXT":                                      //creates each string of text
...
case "//":                                        //ignores comments
...
case "END":                                       //stops reading file
obj.close();
break;
}
}
Scene scene = new Scene(root, fwidth, fheight, Color.BLACK);
stage.setTitle("poop");
stage.setScene(scene);
stage.show();
}
catch (FileNotFoundException fileNotFoundException) {
fileNotFoundException.printStackTrace();
}
}
/**
* The main method
* @param args
*/
public static void main(String[] args) {
launch(args);
}
}

here is the error:

Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1070)
at java.util.Scanner.findWithinHorizon(Scanner.java:1670)
at java.util.Scanner.hasNextLine(Scanner.java:1500)
at sample.Graphic.start(Graphic.java:69)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
... 1 more
Exception running application sample.Graphic
Process finished with exit code 1

idk if it's a simple fix and i'm just missing it or what but if anyone can help it would be much appreciated.

答案1

得分: 3

将您的循环放置在try-with-resources块内部,这样它将自动关闭扫描仪,因为Scanner实现了Closeable。

try (Scanner obj = new Scanner(new File("star.txt"))) {
    //将整个while循环放在此处
}

您跳出了switch/case,因此您应该在try块内部,在循环正上方创建一个布尔变量,然后在"END"处将其设置为true。
然后在循环中检查该变量的值,如果为true,则像这样跳出循环:

在while循环之上:

boolean shouldBreak = false;

结束的case:

case "END":
    shouldBreak = true;
    break;

然后在循环的结尾(内部):

if (shouldBreak) break;
英文:

Place your loop inside a try-with-resources block, then it will close the scanner by itself, since Scanner implements Closeable.

try (Scanner obj = new Scanner(new File("star.txt"))) {
//Place your whole while loop here
}

You break out of the switch/case, so you should create a boolean inside the try, right above your loop, then set it to true on "END".
Then check the variable's value in your loop and if it's true, then break out of the loop like so:

Above the while loop:

boolean shouldBreak = false;

End case:

case "END":
shouldBreak = true;
break;

Then at the end of your loop (inside)

if(shouldBreak) break;

huangapple
  • 本文由 发表于 2020年10月17日 07:13:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64397546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定