Write/Reading Files in Java - java

I am working on an assignment and cannot get this method to produce the correct output to the file. I am supposed to get the mean and write it to the file. Their is the StatsDemo class and the StatsFile class. I am kind of a beginner at Java so I'd like just a little help. My method in the StatsFile class is currently like this:
//returns the calculated arithmetic average
public double calculateMean(String filename) throws FileNotFoundException
{
// declare variables step 5
double accumulator = 0.0;
int counter =0;
String line;
try{
File input = new File(filename);
//create a Scanner object passing it the File object
Scanner keyboard = new Scanner(input);
//for (int i = 0; i < input.length(); i++){
// Read a double from the file.
while(keyboard.hasNextDouble()){
accumulator += keyboard.nextDouble();
// Add to counter
counter++;
}
keyboard.close();
}catch(FileNotFoundException e){
}
return (accumulator/counter);
}
The demo is as such:
import java.util.Scanner;
import java.text.DecimalFormat;
import java.io.*;
public class StatsDemo {
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
DecimalFormat threeDec = new DecimalFormat("0.000");
Scanner keyboard = new Scanner(System.in);
String filename; // the user input file name
System.out.print("Enter the file name: ");
filename = keyboard.nextLine();
FileStats fileObj = new FileStats(filename);
try{
PrintWriter name = new PrintWriter("Results.txt");
name.println("mean = " + threeDec.format(fileObj.getMean()));
name.println("Standard Deviation = " + threeDec.format(fileObj.getStdDev()));
name.close();
}catch(IOException e){
System.out.println("Error");
}
}
}
The catches and throws still kind of confuse me. My issue is that it currently gives me a question mark instead of the mean when i open the file. Any help will be appreciated.

If an exception that occurs within the try block, control jumps to the catch block. You should think about what should happen in that case. You may be able to correct the problem and continue; you may wish to look at the problem and rethrow and exception, or you may wish just to let your caller handle the problem. In the last case, you don't need a catch at all, you can just need a throws on your method declaration.
Catching an exception and doing nothing is rarely a good idea as the problem is just being ignored. Remember that code flow will carry on after the catch clause unless another exception is thrown, so if the file does not exist, you will still process the return (accumulator/counter) line, which is not what you want.
Looking at your code, your method already throws a FileNotFoundException, so just remove the try and the catch.

Related

Project throwing IOException after readFile method call [duplicate]

This question already has answers here:
What is a stack trace, and how can I use it to debug my application errors?
(7 answers)
Closed 3 years ago.
I'm currently writing a program that will read in a CSV file that contains data about age, height, and weight. My issue is, when I call in the method that reads the file from the main, it throws an IOException. I'm not sure what's causing this, and as this is for a project, I am not allowed to throw an IOException from the main() method. I inserted a output print line to try and spot where the bug occurs, because debug mode in eclipse is not allowing me to do so, and it seems that the error occurs before the readFile() method even starts.
I am extremely rusty in java and code in general, and am taking this class after not touching coding for an extended period of time. I'm not sure exactly where to start to try and debug this IOException.
public class Project1 {
public static void main(String[] args) {
//main method declaring project object
Project1 project = new Project1();
String fileName = project.checkArgs(args);
File blah = null; //temporary name for the file don't pay attention to it
try {
blah = project.getFile(fileName); //gets the file and sets it to variable in main
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
project.readFile(blah, 500); //trying to read in file of 2d array in the readFileMethod
}
catch (IOException i) { //method gets caught here
System.out.println("IOException");
}
}
//readFile METHOD
public String[][] readFile(File file, int numRecords) throws IOException {
//two parameters: file, being read in this method, and numRecords the amount
//of elements in the array (I haven't done anything with numRecords yet and I
//believe this may possibly be the source of the error
Scanner reader = new Scanner(file); //scanner to read in file
//2d array to be passed back to main
String[][] data = new String[numRecords][3];
System.out.println("hi"); //test for IOException, doesn't get to this point
int iteration = 0; //to skip first line of text in csv file
while (reader.hasNextLine()) { //loading in elements to 2d array
iteration++;
if (iteration < 1) {
reader.nextLine();
continue;
}
else {
String list[] = reader.nextLine().trim().split(",");
for (int i = 0; i < numRecords; i++) {
for (int j = 0; j < 3; j++) {
data[i][j] = list[j];
System.out.println(data[i][j]);
}
}
}
}
return data;
}
The program catches the IOException in method main().
I can't find the reason, please provide a stack trace (i.printStackTrace()).
Since you do not use the delimiters of the scanner, you may try another way:
BufferedReader br = new BufferedReader(new FileReader(file), bufferSize);
String line;
if ((line = br.readLine()) != null) {
// process the line
}

Calling method with IOException

I cannot call this function that handles a text file.
I try to call it but an exception is thrown. I tried various approaches but nothing has worked so far.
public static void spracujSubor () throws IOException {
File f = new File("test.txt");
Scanner sc = new Scanner(f);
try {
while(sc.hasNextLine()) {
String nazov = sc.next();
String model = sc.next();
double cena = sc.nextDouble();
Auto rep = new Auto(nazov, model,cena);
aPozicovna.aAuto.add(rep);
}
} catch(IOException ioe){
System.err.println(ioe);
}
sc.close();
}
First of all, we can't help you figure out what causes the IOException if you don't (at least) show us the exception's message. The complete stacktrace would be ideal, but the message you help a lot.
There are multiple places where the IOException could be thrown, including:
In the new Scanner(f) if the file doesn't exist, isn't readable, has the wrong pathname, and a few other cases.
In the various calls on the Scanner object in the loop, depending on your file syntax.
In the close() call ... in theory.
Some of these are inside the try-catch. Others are before or after it. For the cases inside the try catch, you are catching the exception, printing a message, and then proceeding as if nothing happened. That is bad. Here is a better structure ... that doesn't squash the exceptions.
public static void spracujSubor () throws IOException {
File f = new File("test.txt");
try (Scanner sc = new Scanner(f)) {
while(sc.hasNextLine()) {
String nazov = sc.next();
String model = sc.next();
double cena = sc.nextDouble();
Auto rep = new Auto(nazov, model,cena);
aPozicovna.aAuto.add(rep);
}
}
}
Note that since the Scanner is an Autocloseable, it will be closed automatically when you exit the try-with-resources.

Need to break my main method into smaller methods

I have written the following code for a lab assignment, however, my professor wants me to break my main method down into other methods and call those methods in the main method. I tried creating methods for creating the input and output streams, and I tried to create a method for the actual writing of the reverse file but I am getting no where. Can someone point me in the right direction? do I need to create another class that I will instantiate and call these methods on? I'm new to java, so any help is appreciated!
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
/**
* Reads lines of text from a file named testclass.txt and writes them to a file
* named output.txt in reverse order.
*/
public class ReverseFile {
public static void main(String[] args) {
Scanner fileRead; // input stream for reading text file.
PrintWriter fileWrite; // output stream for writing text file.
ArrayList<String> fileLines; // An ArrayList for holding the lines of the text file.
fileLines = new ArrayList<String>();
try { // Create the input stream.
fileRead = new Scanner(new File("testclass.txt"));
}
catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return; // End the program by returning from main().
}
try { // Create the output stream.
fileWrite = new PrintWriter(new FileWriter("output.txt"));
}
catch (IOException e) {
System.out.println("Can't open file output.txt");
System.out.println("Error: " + e);
fileRead.close(); // Close the input file.
return; // End the program.
}
while ( fileRead.hasNextLine() ) { // Read until end-of-file.
String textLine = fileRead.nextLine();
System.out.println(textLine);
fileLines.add(textLine);
}
// Output the text in reverse order.
for (int i = fileLines.size()-1; i >= 0; i--)
fileWrite.println(fileLines.get(i));
//System.out.println(reverseLines);
System.out.println("Done, check output.txt");
fileRead.close();
fileWrite.close();
} // end of main()
}
Ideally each method should do one thing only and have a name that makes it clear what that one thing is.
My suggestion is that your main method should look something like:
public static void main(String[] args) {
List<String> lines = createAndReadInputStream();
reverse(lines);
createAndWriteOutputStream(lines);
}
That makes it perfectly clear to the reader exactly what the method does and all implementation details are in other methods.
Then do the same for the next method:
private List<String> createAndReadInputStream() {
Scanner inputScanner = createInputStream();
return scanToLines(inputScanner);
}
And so on. If correctly structured your class variables all become locally scoped variables and your code is straightforward and easy to read. You'll also find you need far fewer comments to explain what's happening: the names of the methods are generally enough on their own.
If you are interested in learning more about why your professor asked for this, and how to go about doing it, I highly recommend the book "Clean Code" by Robert Martin. The software development team of which I am a part (80 people in 11 agile teams) adopted it several years ago and the quality, readability and maintainability of our code has improved out of sight. While it takes some getting used to it's worth the effort. In my view the old adage that more code means more bugs is just completely false - as long as the extra code is there for readability, testability, maintainability then it means fewer bugs not more.
Here is an example. Move this section of code:
try { // Create the input stream.
fileRead = new Scanner(new File("testclass.txt"));
}
catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return; // End the program by returning from main().
}
into a new private method called createInputStream within the ReverseFile class. Call the new member from the point in the code where you removed the section. Don't forget to return "fileRead" from the method.
What about this:
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
/** * Reads lines of text from a file named testclass.txt and writes them to a file * named output.txt in reverse order. */
public class ReverseFile {
public static ArrayList<String> readFile(String fileName) {
Scanner fileRead; // Scanner for reading text file.
// Try to open file for reading
try {
fileRead = new Scanner(new File(fileName));
// On failure -> print message & return null
} catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return null;
}
// Create ArrayList for readed lines
ArrayList<String> fileLines = new ArrayList<String>();
// Read file line-by-line until end-of-file.
while ( fileRead.hasNextLine() ) {
String textLine = fileRead.nextLine(); // Read next line
System.out.println(textLine); // Print line to terminal
fileLines.add(textLine); // Add line to ArrayList
}
// Close scanner -> will close allso opened file
fileRead.close();
// Return loaded lines
return fileLines;
}
public static void createReversedFile(String filename, ArrayList<String> fileLines) {
PrintWriter fileWrite; // PrintWriter for writing text file.
// Try to open file for writing
try {
fileWrite = new PrintWriter(new FileWriter(filename));
// On failure -> print message & return
} catch (IOException e) {
System.out.println("Can't open file output.txt");
System.out.println("Error: " + e);
fileRead.close(); // Close the input file.
return;
}
// Output the text in reverse order
for (int i = fileLines.size()-1; i >= 0; i--) {
fileWrite.println(fileLines.get(i));
//System.out.println(reverseLines);
}
System.out.println("Done, check " + filename);
// Close PrintWriter -> will close allso opened file
fileWrite.close();
}
public static void main(String[] args) {
// Read file & store it's lines into ArrayList
ArrayList<String> fileLines = readFile("testclass.txt");
// If file was not loaded due to FileNotFoundException exception -> exit
if (fileLines == null) {
return;
}
// Create reversed output.txt file
createReversedFile("output.txt", fileLines);
}
}

How do I resolve these exceptions?

To be fair, I'm not getting these exceptions but merely trying to find a away to cover these exceptions. The exceptions are NosuchElementException and NumberFormatException.
Note: This programs works perfectly because the txt file is fine. However, introduce anything that is not a number and it will fail.
Here is the main class where the problem could occur:
BankReader.java
package bankreader;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class BankReader
{
public static void main(String[] args)
{
BankReader reader = new BankReader();
Scanner scan = new Scanner(System.in);
String fileName = "";
boolean finished = false;
while(!finished)
{
try
{
System.out.print("Enter the name of the file: ");
fileName = scan.nextLine();
scan = reader.checkFile(fileName, scan);
reader.readFile(scan);
finished = true;
}
catch(IOException ex)
{
System.out.print("\nThis file does not exist or had");
System.out.println(" characters that were not numbers. Please enter a different file.\n");
}
}
scan.close();
}
public Scanner checkFile(String fileName, Scanner scan) throws IOException
{
File file = new File(fileName);
scan = new Scanner(file);
return scan;
}
public void readFile(Scanner scan)
{
String accountNumber = "";
double accountBalance = -1;
Bank bank = new Bank();
while(scan.hasNext())
{
accountNumber = scan.next();
accountBalance = Double.parseDouble(scan.next());
BankAccount bankAccount = new BankAccount(accountNumber, accountBalance);
bank.addAccount(bankAccount);
}
if (bank.numberOfAccounts() > 0)
{
BankAccount maxBalance = bank.getHighestBalance();
System.out.println(maxBalance.getAccountNumber() + ": " + "$" + maxBalance.getBalance());
}
else
System.out.println("\nThe file had no accounts to compare.");
}
}
Here is the txt file I'm working with:
346583155444415 10000.50
379611594300656 5000.37
378237817391487 7500.15
378188243444731 2500.89
374722872163487 25000.10
374479622218034 15000.59
342947150643707 100000.77
So even though this is my own txt file, what if I was accessing a text file that a character that wasn't a number or had an account number but no balance and vice versa. I would like to know how I can deal with these exceptions.
What I've tried:
I've tried to do scan.nextLine() to move away from the exception but it just introduces another exception.
I've also tried to use a method that uses regex to check if the string is a number. The problem is I'm using a variable that is not a string and I would rather not create more checks.
It seems to me that no more what I do, I can't recover my scanner after an exception has occurred.
before parsing you can test if it is a double with scan.hasNextDouble and parse or read the number only then else you set default value and move next by reading the incorrect value and dont do anything with it

Using scanner with a prompt and user input

I tried to do counting lines, words, character from user "inputted" file.
After this show counting and keep asking again.
If file doesn't exist print all data which have been counted during running.
Code:
public class KeepAskingApp {
private static int lines;
private static int words;
private static int chars;
public static void main(String[] args) {
boolean done = false;
//counters
int charsCount = 0, wordsCount = 0, linesCount = 0;
Scanner in = null;
Scanner scanner = null;
while (!done) {
try {
in = new Scanner(System.in);
System.out.print("Enter a (next) file name: ");
String input = in.nextLine();
scanner = new Scanner(new File(input));
while(scanner.hasNextLine()) {
lines += linesCount++;
Scanner lineScanner = new Scanner(scanner.nextLine());
lineScanner.useDelimiter(" ");
while(lineScanner.hasNext()) {
words += wordsCount++;
chars += charsCount += lineScanner.next().length();
}
System.out.printf("# of chars: %d\n# of words: %d\n# of lines: ",
charsCount, wordsCount, charsCount);
lineScanner.close();
}
scanner.close();
in.close();
} catch (FileNotFoundException e) {
System.out.printf("All lines: %d\nAll words: %d\nAll chars: %d\n",
lines, words, chars);
System.out.println("The end");
done = true;
}
}
}
}
But I can't understand why it always show output with no parameters:
All lines: 0
All words: 0
All chars: 0
The end
Why it omits all internal part.
It may be coz I'm using few scanners, but all look ok.
Any suggestions?
UPDATE:
Thanks all who give some hint. I rethinking all constructed and rewrite code with newly info.
To awoid tricky scanner input line, I used JFileChooser:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JFileChooser;
public class KeepAskingApp {
private static int lines;
private static int words;
private static int chars;
public static void main(String[] args) {
boolean done = false;
// counters
int charsCount = 0, wordsCount = 0, linesCount = 0;
Scanner in = null;
Scanner lineScanner = null;
File selectedFile = null;
while (!done) {
try {
try {
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
selectedFile = chooser.getSelectedFile();
in = new Scanner(selectedFile);
}
while (in.hasNextLine()) {
linesCount++;
lineScanner = new Scanner(in.nextLine());
lineScanner.useDelimiter(" ");
while (lineScanner.hasNext()) {
wordsCount++;
charsCount += lineScanner.next().length();
}
}
System.out.printf(
"# of chars: %d\n# of words: %d\n# of lines: %d\n",
charsCount, wordsCount, linesCount);
lineScanner.close();
lines += linesCount;
words += wordsCount;
chars += charsCount;
in.close();
} finally {
System.out.printf(
"\nAll lines: %d\nAll words: %d\nAll chars: %d\n",
lines, words, chars);
System.out.println("The end");
done = true;
}
} catch (FileNotFoundException e) {
System.out.println("Error! File not found.");
}
}
}
}
Couple of issues (actually there are many issues with your code, but I will address the ones directly related to the output you have posted):
First of all, the stuff in the catch block only happens if you get a FileNotFoundException; that's there to handle and recover from errors. I suspect you meant to put a finally block there, or you meant to do that after the catch. I suggest reading this tutorial on catching and handling exceptions, which straightforwardly describes try, catch, and finally.
Once you read that tutorial, come back to your code; you may find that you have a little bit of reorganizing to do.
Second, with the above in mind, it's obvious by the output you are seeing that you are executing the code in that catch block, which means you are getting a FileNotFoundException. This would be caused by one of two (possibly obvious) things:
The file you entered, well, wasn't found. It may not exist or it may not be where you expect. Check to make sure you are entering the correct filename and that the file actually exists.
The input string is not what you expect. Perhaps you read a blank line from previous input, etc.
Addressing reason 2: If there is already a newline on the input buffer for whatever reason, you will read a blank line with Scanner. You might want to print the value of input just before opening the file to make sure it's what you expect.
If you're seeing blank lines, just skip them. So, instead of this:
String input = in.nextLine();
scanner = new Scanner(new File(input));
Something like this instead would be immune to blank lines:
String input;
do {
input = in.nextLine().trim(); // remove stray leading/trailing whitespace
} while (input.isEmpty()); // keep asking for input if a blank line is read
scanner = new Scanner(new File(input));
And, finally, I think you can work out the reason that you're seeing 0's in your output. When you attempt to open the file with new Scanner(new File(input)); and it fails because it can't find the file, it throws an exception and the program immediately jumps to the code in your catch block. That means lines, words, and chars still have their initial value of zero (all code that modifies them was skipped).
Hope that helps.
Your println()s are in a catch block
} catch (FileNotFoundException e) {
System.out.printf("All lines: %d\nAll words: %d\nAll chars: %d\n",
lines, words, chars);
System.out.println("The end");
done = true;
}
That means you caught a FileNotFoundException. I think you can figure out from here.

Categories

Resources