InSpace
InSpace

Reputation: 31

Basic Java IO, always throwing exception

I'm new to Java and am trying to write a program that has one argument, the path of a text file. The program will locate the text file and print it out to the screen. Eventually I'm going to build this to format the given text file and then print it out to an outfile, but I'll get there later.

Anyways my program is always throwing and IOException and I'm not sure why. Given the argument C:\JavaUtility\input.txt , I receieve "Error, could not read file" during runtime. My code is located below.

import java.io.*;

public class utility {
    public static void main(String[] path){

        try{

        FileReader fr = new FileReader(path[0]);
        BufferedReader textReader = new BufferedReader(fr);

        String aLine;

        int numberOfLines = 0;
        while ((aLine = textReader.readLine()) != null) {
            numberOfLines++;
        }

        String[] textData = new String[numberOfLines];

        for (int i=0;i < numberOfLines; i++){
            textData[i] = textReader.readLine();
        }

        System.out.println(textData);

        return;
        }
        catch(IOException e){
            System.out.println("Error, could not read file");

        }       
    }       
}

[EDIT] Thanks for all the help everyone! So given my end goal, I thought it would still be useful to find the number of lines and store in a finite array. So I ended up writing two classes. The first, ReadFile.java found the data I wanted and handles most of the reading. The second FileData.java invokes the methods in ReadFile and prints out. I've posted them below incase someone later finds them useful.

package textfiles;
import java.io.*;

public class ReadFile {

        private String path;

        public ReadFile(String file_path){
            path = file_path;
        }

        int readLines() throws IOException{

            FileReader file_to_read = new FileReader(path);
            BufferedReader bf = new BufferedReader(file_to_read);

            String aLine;
            int numberOfLines = 0;

            while ((aLine = bf.readLine()) != null){
                numberOfLines++;
            }
            bf.close();
            return numberOfLines;
        }

        public String[] OpenFile() throws IOException{

            FileReader fr = new FileReader(path);
            BufferedReader textReader = new BufferedReader(fr);

            int numberOfLines = readLines();
            String[] textData = new String[numberOfLines];

            for(int i=0; i < numberOfLines; i++){
                textData[i] = textReader.readLine();
            }

            textReader.close();
            return textData;
        }
}


package textfiles;
import java.io.IOException;

public class FileData {

    public static void main(String[] args)throws IOException{

        String file_name = args[0];

        try{
            ReadFile file = new ReadFile(file_name);
            String[] aryLines = file.OpenFile();

            for(int i=0; i < aryLines.length; i++){
                System.out.println(aryLines[i]);
            }


        }

        catch (IOException e){
            System.out.println(e.getMessage());
        }


    }
}

Upvotes: 1

Views: 2875

Answers (3)

Rutesh Makhijani
Rutesh Makhijani

Reputation: 17225

As mentioned by @mikeTheLiar you are at End Of File. BufferedReader reference is File Handler with an internal cursor pointing to current position in file. As you fire readLine() method, the pointer reads characters till it reaches new line character, returning the string. The pointer is set to new position. Once you read all the lines then readLine() returns null. After that if you call readLine() it will throw IOException. As noted by @EJP

One of the best coding rules while using IO API is to always check for EOF condition - the way you have in first loop. Once you reach EOF after that you should not call read method on the same reference without resetting the cursor - this can be done by calling reset() method.

IMHO, in your case there is no need for second loop. You can achieve the functionalty using one loop only.

import java.io.*; 
import java.util.ArrayList;

public class utility { 
public static void main(String[] path){ 

    try{ 

    FileReader fr = new FileReader(path[0]); 
    BufferedReader textReader = new BufferedReader(fr); 

    String aLine; 

    int numberOfLines = 0; 
    ArrayList readLines = new ArrayList();
    while ((aLine = textReader.readLine()) != null) { 
        numberOfLines++; 
        readLines.add(aLine);
    } 
    //Assuming you need array of lines, if not then you can print the lines directly in above loop
    String[] textData = readLines.toArray(); 

    System.out.println(textData); 

    return; 
    } 
    catch(IOException e){ 
        System.out.println("Error, could not read file"); 

    }        
 }     
}

EDIT

I tried your code - it is working fine and printing the array reference. As suggested in comments the problem is with source (file might not be readable due to security or any other reason) - if you can print the exception message and get the exact line number where exception is thrown it would be helpful.

Couple of observations apart from the IO exception:

You are trying to open the file twice. readLines() method is called from within OpenFile(). Following the sequence of code file is first opened in OpenFile() when you create textReader. After that you are calling readLines() which is again trying to open the file when you create file_to_read.

You should try to avoid that and in your flow you should call int numberOfLines = readLines(); before FileReader fr = new FileReader(path);

Again IMHO there should be only one method and you should iterate over the file only once - both from efficience/performance and code maintainability perspective. You can change your ReadFile class as follows:

package textfiles;                     
import java.io.*;
import java.util.ArrayList;                     

public class ReadFile {                     

    private String path;                     

    public ReadFile(String file_path){                     
        path = file_path;                     
    }                     
    //You need not have separate file for counting lines in file
    //Java provides dynamic sized arrays using ArrayList
    //There is no need to count lines             
    public String[] OpenFile() throws IOException{                     

        FileReader fr = new FileReader(path);                     
        BufferedReader textReader = new BufferedReader(fr);                     

        ArrayList fileLines = new ArrayList();
        String readLine = textReader.readLine();
        while(readLine != null){                     
            fileLines.add(readLine);
            readLine = textReader.readLine();                     
        }                     

        textReader.close();                     
        return fileLines.toArray();                     
    }
  }

Another small observation: in some places the java variable naming conventions are not followed. OpenFile() method should be openFile() and file_to_read should be fileToRead

Upvotes: 1

User1000547
User1000547

Reputation: 4301

You're at the end of the file. When you determine the number of lines in the file, you've read until the end of the file,and the EOF Flag is set. [Edit: As @EJP notes below, BufferedReader returns null reading past the end of a file. The fact your reader isn't where you want it, however, remains true.] In the past, I've hacked around this simply by closing and re-opening the file. Alternatively, look into Array Lists or simple Lists. They're dynamically re-sizing, so you don't need to know the number of lines in the file ahead of time.

Upvotes: 6

user207421
user207421

Reputation: 310883

Contrary to several answers here, readLine() does not throw an exception at end of file, it just keeps returning null. Your problem is being masked by another one. Never just make up your own error messages. Always print the one that comes with the exception. If you had done that you would probably have found the problem immediately. Almost certainly you weren't able to open the file at all, either because it wasn't there or you didn't have read access. The exception will tell you.

Upvotes: 0

Related Questions