这是用Java传递输入文件的不良做法吗?

时间:2018-02-17 23:54:51

标签: java input try-catch

我有一个主类,它希望通过命令行参数提供输入文件名;如果不是这样,则程序退出并显示错误消息。

我们假设存在一个名为SudokuReducer的类。确保有输入文件后,main函数会将输入文件(不仅仅是文件名)传递给SudokuReducer实例。

我想知道的是,这种糟糕的形式/做法?将整个扫描放在try / catch中是不是错了?因为那时如果我想在try / catch之外的'main'中声明SudokuReducer实例而不是in,我不能因为它''尝试无法识别'fileInput',因为它在'try'中的范围有限“

有更好的方法吗?这就是我所拥有的:

import java.io.File;

public class MainMV {

File inputFile;

public static void main(String args[]) {

    // check if file is entered and handle exception
    try {
        if (args.length > 0) {
            File inputFile = new File(args[0]);

            System.out.println("Processing file");
            SudokuReducer reducer = new SudokuReducer(inputFile);

        } else {
            System.out.println("No file entered.");
            System.exit(1);
        }

    } catch (Exception e) {
        System.out.println("File failed to open.");
        System.exit(1);
    }

}

}

2 个答案:

答案 0 :(得分:1)

要回答标题中的问题:不,这不是不好的做法,如果该方法需要File来完成其工作。

另一种选择是通过String;并且这是一个糟糕的选择,因为它没有表明该参数应该代表某种File

也许更好的选择是将InputStream传递给方法,因为a)清楚地传达了它将用于输入(而不是File你会写的); b)它更灵活,因为它不必引用磁盘上的文件。

回答问题中的问题:不,将一切包装在一次尝试/捕获中并不是一个很好的做法。这使得很难区分失败模式:许多不同的东西可能会在您的代码中出错,并且分开处理这些事情会更好。提供特定的失败信息。

构建代码的更好方法是这样的:

if (args.length == 0) {
  System.out.println("No file entered.");
  System.exit(1);
}

File inputFile = new File(args[0]);
System.out.println("Processing file");
try {
  SudokuReducer reducer = new SudokuReducer(inputFile);
  // Do something with reducer.
} catch (IOException e) {
  e.printStackTrace();
  System.out.println("File failed to open.");
  System.exit(1);
}

请注意,这有一个小块,处理特定的错误,而不是一个很大的块,错误处理与导致错误的东西分开。

另外,请注意它没有抓住Exception:除非必须这样做,否则你真的不想这样做,因为你没有正确处理会遇到的异常必须以特殊方式处理(即InterruptedException)。抓住最具体的异常类型。

答案 1 :(得分:0)

根据我的理解,Java通过值传递参数作为对象的引用,这对我来说非常混乱。

Link to explanation of Pass by Reference vs Pass by Value

Link to explanation of the Java implementation

根据生成SudokuReducer类实例所需的文件信息量,这可能会产生很大的开销。如果是这种情况,您将要逐行解析您的输入 在你的主要方法中有这样的东西。

 try {
     SudokuReducer reducer = SudokuReducer.makeSudokuReducer(args[0])
  }
 catch(Exception e) { 
     System.out.println("No file entered.");
     System.exit(1);
 }

Here's an example of reading a file line by line 有很多方法可以做到这一点,但我能想到的最有效的方法是使用Java 8的Stream和Files类。

方法签名看起来像这样:

public static SudokuReducer makeSudokuReducer(String filename) {
    //Open file
    //Parse input line by line
    //Use information to create a new instance of your class
    //Return the instance of this class
}

您可以在任何地方调用此静态方法,从文件名生成类的新实例。