astrimbu
astrimbu

Reputation: 61

Read filename from command-line and use it outside main method

I have to write a program that counts the lines in a file, the file is specified when starting the program:

java CountText textFile.txt

In the main method I use this code to get the filename entered in cmd:

if ( args.length > 0 ) {
    String file = args[0];
}

Outside the main method I want to refer to this filename again:

public void Lines() throws Exception {      
    FileReader fr = new FileReader ( file );

The symbol can't be found (which I don't get because main method is public and static?). I feel like it's a simple solution, but I can't figure it out.

EDIT: Solved by Hovercraft Full Of Eels (also Travis). It is a scope issue which is solved by passing the String into the method via its parameter.

public class CountText {
public static void main ( String args[] ) throws Exception {
    CountText count = new CountText();

    if ( args.length > 0 ) {
        String file = args[0];
        count.Lines( file );
        count.Words( file );
        count.Characters( file );
    }
}

public void Lines ( String file ) throws Exception {        
    FileReader fr = new FileReader ( file );

Upvotes: 0

Views: 7394

Answers (3)

Tulains Córdova
Tulains Córdova

Reputation: 2639

The main method is an entry point for a program.

The main method can even be in a different class that the one containing the program logic.

You must declare a private instance variable for the file path and pass it in the constructor of the class.

In the main method, you create an instance of your class.

public class SomeClass {

    private String filePath;

    // this is the constructor of the class
    public SomeClass(String filePath){
        this.filePath = filePath;
    }

    public void lines() throws Exception {      
        FileReader fr = new FileReader ( this.filePath );
        ...
        ...
    }


    public static void main(String[] args) {

        SomeClass o = new SomeClass(args[0]);

    }

}

As I said before you can even delete the main method from SomeClass and move it to, say, MainClass:

public class MainClass{
    public static void main(String[] args) {

        SomeClass o = new SomeClass(args[0]);

    }
}

And you can have more fun: you can even receive more than one file in the command line, instantiate SomeClass more than once, then process each file in batch, since file path is an instance variable, every object is separated and distinct:

public class MainClass{
    public static void main(String[] args) {

        List<SomeClass> list = new ArrayList<SomeClass>();

        for(String s: args){
           list.add(new SomeClass(s));  // create an instansce for each filename in args
        }

        for(SomeClass o: list){
           o.lines();    // run method on each file
        }

    }
}

That's the magic of OOP in action !

Upvotes: 1

Travis
Travis

Reputation: 646

What you're encountering here is a scope problem. Your variable is defined in the main function, so another function cannot access it. We say that the variable file is local to the main function.

One way to use the file variable inside your Lines method so that it accepts a string argument, which you can then pass to it. That would look like

public void Lines( String fileName ) throws Exception {
    // rest of the code here
}

So then you can call the method like so

if ( args.length > 0 ) {
    String file = args[0];
    Lines( file );
}

Upvotes: 3

Austin
Austin

Reputation: 4929

You should declare a field in your class named file with type String.

Something like this

public class SomeClass {

private static String file;

public static void main(String[] args) {
file = args[0];
}

}

Upvotes: 0

Related Questions