Search code examples
javaoutputprintwriter

Writing output to text file in a class in java?


I'm having an issue of writing output to a text file. I'm not too sure on how to go about it. I've tried to write output by writing something along the lines of- Writer is an object of the printWriter class:

This is trimmed down substantially but it boils down to.

Writer.println(sortRI());

I can't write that statement as the method itself- and all methods in this class I'm trying to write to an output file for are void.

So my question is how do I write output to a text file from my methods which are void- they print out their results via a few print statements. Is there a way I can instantiate a writer and use the writer to print the methods. An example of one of the methods is shown below:

ZipCodeLocation[] data2 = new ZipCodeLocation[];

public class Processor
{
  ...

  public void readData(){

  ...

  }

public void findSpringfield()
{
    System.out.println("------------------------------------------------------------------------");
    System.out.println("SPRINGFIELD ZIP CODES");

    for(int i=0; i < data2.length ; i++)
    {
        if(data2[i].getpostalCity().replaceAll("\"","").contains("SPRINGFIELD"))
        {
          System.out.println(data2[i].getzipCode().replaceAll("\"",""));  //Prints out zipCodes that have Springfield in them
        }
    }
}

Instead of printing the message to System.out in the console, how could I have it write the output of the method to a text file?


Solution

  • You have asked a very good question, because it describes an instance of a design consideration common to all software.

    The topic here is separation of business logic from interfaces. Even more generally, it's a discussion of well-defined responsibilities in an object-oriented program.

    Ideally your business logic would return a data structure, which would allow the caller to do anything desired with the result, like write it to a file or display it in a web page.

    public List<String> findSpringfield()
    {
        List<String> results = new ArrayList<String>();
        for(int i=0; i < data2.length ; i++) {
            if(data2[i].getpostalCity().contains("SPRINGFIELD")) {
                results.add(data2[i].getzipCode().replaceAll("\"",""));  //Collects zipCodes that have Springfield in them
            }
        }
        return results;
    }
    

    If that's not an option, at the absolute minimum you would want to modify your methods to accept a PrintStream parameter.

    public void findSpringfield(PrintStream out)
    {
        out.println("------------------------------------------------------------------------");
        out.println("SPRINGFIELD ZIP CODES");
    
        for(int i=0; i < data2.length ; i++) {
            if(data2[i].getpostalCity().contains("SPRINGFIELD")) {
                out.println(data2[i].getzipCode().replaceAll("\"",""));  //Prints out zipCodes that have Springfield in them
            }
        }
    }
    

    That way you could call it like

    findSpringfield(System.out);
    

    Or you could pass it a different PrintStream instance than System.out, one that points to your own file.

    Finally, if neither of the above options will work for you, I'm going to tell you how to do something which is very bad practice. You can redirect System.out to a file of your choosing. As I said, this is a terrible idea; use it only as a last resort in a very limited scope.

    System.out = new PrintStream("somePath/someFile.txt");
    

    Also, as a design improvement, consider generalizing your findSpringfield method to accept a String postalCity parameter so you can reuse it to find zip codes for other cities.

    public List<String> zipsByCity(String postalCity)
    {
        // use postalCity to filter results, rather than hardcoded "SPRINGFIELD" string
    }