Reading an Input File and Getting no output from code - java

I am assigned to write to another document using data from an input file, and calculating the mean and standard deviation from that file. I have an issue where my code is compiling correctly (according to Dr.Java) but is not giving an output to the output file. I have the code attached that I think is the problem area. It may either be the loops used or reading the file before the loops. Could anyone tell me if those places are the places of error?
// Create a File object passing it the filename
File readFile = new File(filename);
// Create a Scanner object passing File object
Scanner inputFile = new Scanner(filename);
// Perform a priming read to read the first line of the file;
line = inputFile.nextLine();
while (inputFile.hasNext()) //create a loop that continues until you are at the end of the file
{
while( Double.parseDouble(line) != -1)
{
sum += Double.parseDouble(line); //convert the line into a double value and add the value to the sum
count++; //increment the counter
line = inputFile.nextLine(); //read a new line from the file
}
mean = sum/count;
}
inputFile.close();
The output file code:
// Create a FileWriter object using "OutputFileProcess.txt"
File file = new File("OutputFileProcess.txt");
FileWriter fw = new FileWriter(file);
// Create a PrintWriter object passing the FileWriter object
PrintWriter outputFile = new PrintWriter("OutputFileProcess.txt");
// Print the results to the output file
outputFile.println(mean);
outputFile.println(stdDev);
// Close the output file
outputFile.close();
The code needs two loops, one to continue until the ned, and one to exclude any negative numbers in the text file. I should also introduce myself. I am Joe.

This might not be the core of your problem, but one of your while loops is obsolete.
If the inner condition
Double.parseDouble(line) != -1
becomes false, the outer while loop will not change the value of line and the inner while loop will never be entered anymore.
So at the moment the whole algorithm stops at the first -1.
A better way to write this down would be
while (inputFile.hasNext())
{
final String line = inputFile.nextLine();
final double lineAsDouble = Double.parseDouble(line);
if (lineAsDouble != -1D) {
sum += lineAsDouble;
count++;
}
}
final double mean = (double) sum / (double) count;
You should also consider parsing and comparing the values as Integers (if they all are), since comparing doubles with == is always dangerous.

Related

Array will only set values to "0" when writing from a text file

String path1, path2;
int count = 0, i = 0;
path1 = args[0];
File file = new File(path1);
FileReader reader = new FileReader(file);
Scanner inputFile = new Scanner(reader);
while(inputFile.hasNextInt()) {
inputFile.nextLine();
count++;
}
int[] array1 = new int[count];
while(inputFile.hasNextInt()) {
//inputFile.nextLine();
array1[i] = inputFile.nextInt();
i++;
}
I never had this issue before, but when I try to write values to an array from a text file containing only int values, one per line, my array only returns all "0"s. instead of the numbers in the text file. I'm not sure if it has to do with me using the command line, but it has the correct argument (file destination) entered in my IDE.
Thanks in advance!
Notice that the exit condition of both while loops are the same. If the first ends then the second one will be jumped over as the condition is immediately false. The pointer of the scanner is already at the end of the file (all numbers have been read by the first loop) so there is nothing left to read.
You have 2 options to fix this issue.
Use an ArrayList: Use an ArrayList<int> object to save the numbers in the first loop. The list grows as numbers are entered so you don't need to know the number of lines before making this object, as opposed to needing to know this to make an array.
Scan the file again: In between the loops close the previous filereader and scanner and create a new one. This new scanner will point to the start of the file again and the second loop will run smoothly.

Why is this bufferedReader returning nulls?

I am trying to read information from a file but for each line it just returns a null
String[] quotes = new String[numberOfLines];
String myLine;
for (int i = 0; i < numberOfLines; i++)
{
myLine = readFile.readLine();
System.out.println(myLine);
quotes[i] = myLine;
}
numberOfLines in the number of lines that actually has characters on them in the file
BufferedReader.readLine returns null if and only if you have read to the end of the file / stream: See javadoc.
Therefore, you have reached the end of file.
Therefore the problem is somewhere else in your code:
how readFile is instantiated / used (e.g. have you opened the right file?), or
how you get the value for numberOfLines.
Unfortunately, we can't go further without seeing the code that does those things. Or better still, an MCVE.
UPDATE
One possibility: the code you use to count the lines has read the file via readFile and left the BufferedReader positioned at the end of file.

Java input/output and Scanner object

Below are two functions in my class, I want to first read the number of lines from a text file, then store the contents in an array. The problem I am having is that if I do not comment out int aNumber = numOfObjects(newInput); the array does not get stored and printed, it's as if numOfObjects function got to the end of the text file, and I can no longer access it. If I comment it out it works fine. I tried adding a second Scanner object but it didn't help. What can I do to make it work?
public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){
newInput = new Scanner(inputFile);
forCapturing = new Scanner(inputFile);
int aNumber = numOfObjects(newInput);
System.out.println(aNumber);
for(int i=0; forCapturing.hasNextLine(); i++){
publicationArray[i] = new Publication();
publicationArray[i].publication_code = forCapturing.nextLong();
publicationArray[i].publication_name = forCapturing.next();
publicationArray[i].publication_year = forCapturing.nextInt();
publicationArray[i].publication_authorname = forCapturing.next();
publicationArray[i].publication_cost = forCapturing.nextDouble();
publicationArray[i].publication_nbpages = forCapturing.nextInt();
System.out.println(publicationArray[i]);
System.out.println("-----------------------------------\n");
}
}
private int numOfObjects(Scanner aScanner){
int count = 0;
while (aScanner.hasNextLine()){
count++;
aScanner.nextLine(); //if this isn't included you'll experience an infinite loop
}
System.out.println(count);
return count;
}
}
There is a way to do this as you want. i.e. by reading through the file 2 times. First to count and then to capture.
Just add below lines after your line int aNumber = numOfObjects(newInput); in correctListItems function.
public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){
newInput = new Scanner(inputFile);
int aNumber = numOfObjects(newInput);
newInput.close();
inputFile.close();
inputFile = new FileInputStream(
new File(
"inputfile.txt"));
System.out.println(aNumber);
forCapturing = new Scanner(inputFile);
for(int i=0; forCapturing.hasNextLine(); i++){
....
....
So basically closing the scanner as well as file is important. And then creating the fileinputreader stream again will reset the file pointer to the beginning of the file. As you might already know, If the input file is not from the project folder, you have to give the complete path.
As a good process, its always better to close both the scanner object and file object after you're done, And then reinitialize the objects to start working on them again.
Hope this helps.
It looks like the scanner class uses an iterator internally. This means that it needs to be closed at some point, which I cant find in your code. Therefore I would (1) add following line to the numOfObects function before the return: “aScanner.close()”.
(2) I would create the second Scanner instance after you called the function, just to be sure. Hope it works.
Cheers!
The scanner doesn't move to the next line unless you call nextLine. So the loop is infinite since you're always on the first line.
But why do you need to know the number of objects in advance? Why not simply use a list instead of publicationArray?
Well, I am not exactly sure but I can be quite certain that the FileInputStream object once the bytes has been read by Scanner once, the scanner will have a token to indicate that a particular line has been read.
How about you change your code to:
public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){
forCapturing = new Scanner(inputFile);
for(int i=0; forCapturing.hasNextLine(); i++){
publicationArray[i] = new Publication();
publicationArray[i].publication_code = forCapturing.nextLong();
publicationArray[i].publication_name = forCapturing.next();
publicationArray[i].publication_year = forCapturing.nextInt();
publicationArray[i].publication_authorname = forCapturing.next();
publicationArray[i].publication_cost = forCapturing.nextDouble();
publicationArray[i].publication_nbpages = forCapturing.nextInt();
System.out.println(publicationArray[i]);
System.out.println("-----------------------------------\n");
}
System.out.println("Number of lines: "+ i);
}
At least with this, you would not have to run 2 loops to the same set of data. better performance too and get the thing you need done in 1 round of a loop

Java file writer

I have been given this task:
Write a program that takes as input a number n and a text string filename and writes n lines to the file where each line is of the form: i: sqrt(i) sqrt(i) sqrt(i). The first column ranges from 1..n whilst the first square root is to one decimal place, the second is to two decimal places and the third is to three decimal places.
And I came up with this code with help from one of my college tutors but..
public static void writeFile(final String filePath, final int n) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
final String format = "%-10s %-10.1f %-10.2f %-10.3f %n";
for(int i=1;i<=n;i++){
final double root = Math.sqrt(i);
writer.write(String.format(format,i+":",root ,root,root));
}
}
}
.... how would I include the text file that's meant to be used? I thought I'd do something similar to filepath = file.txt. for example. But I'm not sure how to incorporate that in the code. I came up with formatting it to the decimal places like the task asks. Would I need to include it in the for loop or outside the loop? Thanks
Your calling method should be passing in the file name as a part of the filePath variable.
If the filePath in the parameter doesnt have a file name, then you can define the file name inside the method and concatenate with the input filePath. You can use the derived file path to create your file writer object.
String completeFilePath = filePath.concat("file.txt");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(completeFilePath))) {
...
}
Also please flush/close the writer object once you are done with the operation.
When you call your method you will pass the filePath as an argument. You only need to set in once in your code
writeFile("textfile.txt",5);

Merge sorting multiple files which have variable word counts

I am splitting a 10 GB file into multiple files of 100000 + few hundred words(since I read upto the line when I encounter 100000 words).
private void splitInputFile(String path) {
try{
File file=new File(path);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String temp;
temp = br.readLine();
String fileName="fileName";
int fileCount = 1;
while(temp!=null){
//TODO Read 100000 words, sort and write to a file. Repeat for the entire file
if(wordsToBeSorted.size()<=100000){
startCounting(temp);
temp=br.readLine();
}//end of if -> place 100000+ words inside the list
else{
Collections.sort(wordsToBeSorted);
fileName = "fileName"+fileCount;
fileCount++;
File splitFile = new File(fileName);
PrintWriter pr = new PrintWriter(splitFile);
for(String word:wordsToBeSorted){
pr.write(word);
pr.write("\n");//check if this works -> 1 word per line
}//end of for
}//end of else
}//end of while
mergeSort(fileCount);
}//end of try
catch(Exception e){
e.printStackTrace();
}
}
private void startCounting(String sb) {
StringTokenizer tokenizer = new StringTokenizer(sb);// Split by space
while (tokenizer.hasMoreTokens()) {
String text = tokenizer.nextToken();
text = text.replaceAll("\\W", "");// Remove all symbols
if("".equals(text.trim()))
continue;
wordsToBeSorted.add(text);
}
}
Now I wonder how to do a sorting with these files. I found out that I am supposed to do a Merge Sort. Considering the facts that each splitFile would have variable number of words(100000 + a few extra words), is it possible to do a merge sort involving files of variable word counts? Or should I follow some other approach to split the file?
is it possible to do a merge sort involving files of variable word counts?
Sure. I assume the goal here is external sorting. Just open up all input files (unless there are really really many, in which case you might have to do multiple runs), read the first word from each. Then identify the input with the smallest word, put that into the output and read the next word from that input. Close and remove any inputs which become empty, unless you have no more inputs.
If you have many inputs, you can use a heap to organize your inputs, with the next word as key. You'd remove the minimal object and then reinsert it after you have proceeded to the next word.

Categories