简体   繁体   English

文件I / O Java提示

[英]File I/O Java prompt

I had a quick questions about prompting and accepting a file name, then making the file-text a scanner object. 我有一个关于提示和接受文件名的快速问题,然后将文件文本作为扫描仪对象。

I want the program to prompt the user to enter the name of a file, until he gets one which exists, then for the file-text to be used as a scanner object. 我希望程序提示用户输入文件的名称,直到他得到一个文件的名称,然后将文件文本用作扫描仪对象。

This is the code I have so far, it works to the point where I exit the while {} loop, but then when I try and process the scanner item like while (input.hasNextLine()) { it gives me an error saying it can't find the scanner item. 这是我到目前为止的代码,它工作到我退出while {}循环的程度,但是当我尝试像while (input.hasNextLine()) {一样处理扫描器项while (input.hasNextLine()) {它给我一个错误说它找不到扫描仪项目。

It's probably a silly mistake, but I just cannot seem to get it. 这可能是一个愚蠢的错误,但我似乎无法得到它。

The whole code is below: 整个代码如下:

import java.io.*;
import java.util.*;

public class PersonalityTest {

public static void main(String[] args) throws FileNotFoundException {

    boolean isFile = false;

        Scanner sc = new Scanner(System.in);
        System.out.print("Input file name? ");
        String fileName = sc.next();
        File inputFile = new File(fileName);

    while (isFile == false) {    
        if (inputFile.exists()) {
            Scanner input = new Scanner(inputFile);
            isFile = true;
        }            
    }

    while(input.hasNextLine()) {

    }
}

The scope of the input variable is local to the while (isFile == false) block. input变量的范围是while (isFile == false)块的本地。 Declare it outside otherwise it won't be visible. 在外面声明它,否则它将不可见。

For the first part "I want the program to prompt the user to enter the name of a file, until he gets one which exists": Move this code: 对于第一部分“我希望程序提示用户输入文件的名称,直到他得到一个存在的文件”:移动此代码:

    Scanner sc = new Scanner(System.in);
    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);

into a method and call it inside the while (isFile == false) block before the exists check (the method should return with the file or make the variable visible in the block by some other means). 进入一个方法并在存在检查之前在while (isFile == false)块内调用它(该方法应该返回文件或通过其他方式使变量在块中可见)。

You can't access input outside the if statement, sice the compiler is not sure, it will pass the test, you can do this: 你不能访问if语句之外的input ,sice编译器不确定,它会通过测试,你可以这样做:

Scanner sc = new Scanner(System.in);
Scanner input = null;
boolean isFile = false;

while (isFile == false){    

    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);

    if (inputFile.exists()){
        input = new Scanner(inputFile);
        isFile = true;
    }            
}

But will throw a NullPointerException if it is null . 但如果它为null则会抛出NullPointerException

I changed the code a little bit, that way, it will not exceed if the file doesn't exist. 我稍微更改了代码,这样,如果文件不存在,它就不会超过。

The Scanner input is local to your if statement. Scanner inputif语句的本地input Your while (input.hasNextLine()) { statement will not work because of that. 你的while (input.hasNextLine()) {语句因此不起作用。 The Java compiler will treat input as a separate Scanner object and that is where the problems crop up , because to the Java compiler, the input that you are trying to use does not exist. Java编译器将input视为单独的Scanner对象, 这就是出现问题的地方 ,因为对于Java编译器,您尝试使用的input不存在。

I would follow MouseEvent's suggested code as it does not run into the problem mentioned above. 我会遵循MouseEvent建议的代码,因为它没有遇到上面提到的问题。

The other answers have addressed your immediate question, but I want to point out a couple of other problems with your code: 其他答案已经解决了您的直接问题,但我想指出您的代码中的其他几个问题:

The way that you are checking to see if the file can be opened is flawed. 您检查文件是否可以打开的方式是有缺陷的。 A better way to write the code is to attempt to open the file ... and retry when there is an exception. 编写代码的更好方法是尝试打开文件...并在出现异常时重试。 For example: 例如:

Scanner input = null;
do {
    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);
    try {
        input = new Scanner(inputFile);
    } catch (IOException ex) {
        System.out.println("Cannot open: " + ex.getMessage());
    }          
} while (input == null);

Why is this better than calling File.exists() ? 为什么这比调用File.exists()更好?

  • There are lots of reasons why you might be able to open a file. 您可以打开文件的原因有很多。 It might not exist at all. 它可能根本不存在。 It might be a directory or a special file that can't be opened as a file. 它可能是无法作为文件打开的目录或特殊文件。 The application might not have permission. 该应用程序可能没有权限。 The file might be on a remote mounted file system and the remote mount might have just died. 该文件可能位于远程安装的文件系统上,远程安装可能刚刚死亡。

  • There is a small time gap between the File.exists() call (and any others that you might make) and actually opening the file. File.exists()调用(以及您可能制作的任何其他调用)与实际打开文件之间存在小的时间间隔。 In that time gap, it is possible that something to your program could do something to make the file unopenable; 在那段时间内,你的程序可能会做一些事情来使文件无法打开; eg it could change its permissions or delete it. 例如,它可以更改其权限或删除它。

The second problem is that your code potentially leaks a file descriptor because the scanner is not closed. 第二个问题是您的代码可能会泄漏文件描述符,因为扫描程序未关闭。 In your specific application (as written) this doesn't matter because you are going to exit the application immediately after using the scanner. 在您的特定应用程序(如书面)中,这无关紧要,因为您将在使用扫描仪后立即退出应用程序。 But if your weren't ... and this code was called lots of times ... you could find that you are unable to open files after a bit. 但是,如果你不是......并且这段代码被多次调用......你会发现你有点无法打开文件。

The correct way to deal with this would be to write your code something like this: 处理这个问题的正确方法是编写如下代码:

public static void main(String[] args) {
    try (Scanner input = openInput()) {
        while (input.hasNextLine()) {
            // do stuff
        }
    }
}

This uses Java 7's new "try with resource" syntax, that ensures that the resource is closed when the try statement completes. 这使用Java 7的新“try with resource”语法,确保在try语句完成时关闭资源。 (You can do the same thing in pre-Java 7 using a try / finally, but the code is a bit more cumbersome.) (您可以使用try / finally在Java 7之前执行相同的操作,但代码有点麻烦。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM