Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I make a class that accepts a file name and can print its contents?

I'm having problems making a class that can read and print from a file. It seems like the file name passed to the constructor isn't actually being assigned to the fileName variable, or maybe I'm doing something wrong with the File and Scanner objects. I really don't know what's wrong or how to fix it. I'm a beginner and just covered using files in my class, so I'm probably missing something obvious. Thanks for any help anyone can give :)

Here's all my code and the instructions for the assignment below.

The assignment was to:

Write a class named FileDisplay with the following methods:

  • constructor: accepts file name as argument

  • displayHead: This method should display only the first five lines of the file’s contents. If the file contains less than five lines, it should display the file’s entire contents.

  • displayContents: This method should display the entire contents of the file, the name of which was passed to the constructor.

  • displayWithLineNumbers: This method should display the contents of the file, the name of which was passed to the constructor. Each line should be preceded with a line number followed by a colon. The line numbering should start at 1.

My code:

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 + "]";
    }

}

I also wrote a driver application to test if the class was working or not:

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());        
    }
}
like image 538
Squirrelstilts Avatar asked Oct 18 '22 15:10

Squirrelstilts


1 Answers

Your problem is here:

File file = new File(fileName);

That statement is outside of your constructor.

It is executed before the constructor kicks in. Therefore the file object is created with the wrong (your default!) name! (see here for further reading)

The better approach here: make your fields final, and use "constructor telescoping"; like this:

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));
}

And now the compiler helps you making sure that your fields get initialized exactly once, in the order that you put down once in your constructor. And you skill have the opportunity to create a FileDisplay object using some "default" file name (where, actually: I would recommend to not do that).

like image 50
GhostCat Avatar answered Oct 20 '22 23:10

GhostCat