我在创建可以从文件中读取和打印的类时遇到问题。看起来传递给构造函数的文件名实际上并没有分配给fileName变量,或者我可能对File和Scanner对象做错了。我真的不知道什么是错的或如何解决它。我是一名初学者,只是在课堂上使用文件,所以我可能会遗漏一些明显的东西。感谢任何人都可以给予的任何帮助:)
以下是我的所有代码和以下作业的说明。
作业是:
使用以下方法编写名为FileDisplay的类:
构造函数:接受文件名作为参数
displayHead:此方法应仅显示文件内容的前五行。如果文件包含少于五行,则应显示文件的全部内容。
displayContents:此方法应显示文件的全部内容,其名称已传递给构造函数。
- displayWithLineNumbers:此方法应显示文件的内容,其名称已传递给构造函数。每行之前应该有一个行号,后面跟一个冒号。行号应从1开始。
我的代码:
import java.io.*;
import java.util.Scanner;
public class FileDisplay {
// just using little random .txt files to test it
private String fileName = "example1.txt";
public FileDisplay(String fileName) throws IOException {
this.fileName = fileName;
}
File file = new File(fileName);
Scanner inputFile = new Scanner(file);
// displays first 5 lines of file
public void displayHead() {
for (int x = 0; x < 5 && inputFile.hasNext(); x++) {
System.out.println(" " + inputFile.nextLine());
}
}
//displays whole file
public void displayContents() {
while (inputFile.hasNext()) {
System.out.println(" " + inputFile.nextLine());
}
}
// displays whole file with line numbers
public void displayWithLineNumbers() {
while (inputFile.hasNext()) {
int x = 1;
System.out.println(x + ": " + inputFile.nextLine());
x++;
}
}
@Override
public String toString() {
return "FileDisplay [someFile=" + fileName + "]";
}
}
我还写了一个驱动程序来测试该类是否正常工作:
import java.io.*;
public class FileDisplayTest {
public static void main(String[] args) throws IOException {
PrintWriter ex1 = new PrintWriter("example1.txt");
ex1.println("apple");
ex1.println("pear");
ex1.println("grape");
ex1.close();
FileDisplay test = new FileDisplay("example1.txt");
test.displayContents();
System.out.println(test.toString());
}
}
答案 0 :(得分:3)
你的问题在这里:
File file = new File(fileName);
该声明在您的构造函数 之外。
在构造函数启动之前执行。因此,使用错误的(默认!)名称创建文件对象! (参见here进一步阅读)
这里更好的方法是:使你的字段最终,并使用“constructor telescoping”;像这样:
private final String fileName;
private final Scanner scanner;
public FileDisplay() {
this("default.txt");
}
public FileDisplay(String fileName) {
this.fileName = fileName;
this.scanner = new Scanner(new File(fileName));
}
现在,编译器帮助确保您的字段只按照在构造函数中放置一次的顺序初始化一次。而且你的技能有机会使用一些“默认”文件名创建一个FileDisplay对象(实际上:我建议不要这样做)。