I'm writing a program in Java which iterates over each line of a text file, this text file contains numbers which are on a separate line, I have successfully made the program read each line and print them to a new file.
However I'm trying to print the average of these numbers to the new file as well, I understand that I would have to treat each line as a float or double (as I'm using decimal numbers) but I'm unsure of how to do this, this is what I've got so far.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class Run {
public static void main(String[] args) throws Exception {
Write(); //call Write method
}
public static void Write() throws Exception {
String line, lineCut;
BufferedReader br = null; //initialise BR- reads text from file
BufferedWriter bw = null; //initialise BR- writes text to file
try
{
br = new BufferedReader(new FileReader("/Users/jbloggs/Documents/input.txt")); //input file
bw = new BufferedWriter(new FileWriter("/Users/jbloggs/Desktop/output.txt")); //output file
line = br.readLine(); // declare string equal to each line
while(line != null) { // iterate over each line
lineCut = line.replaceAll(";" , ","); // replace ; with ,
//lineCut = line.substring(1, line.length());
//int mynewLine = Integer.parseInt(lineCut);
bw.write(lineCut); // write each line to output file
bw.write("\n"); // print each line on a new line
line = br.readLine();
}
System.out.println("success"); //print if program works
br.close();
bw.close();
}
catch(Exception e){
throw(e); // throw exception
}
}
}
Basically this is what you are doing
reading lines from a file
replacing ';' with a ','
writing this modified line to a new file
So in each of above operation, you have never treated the line to be a Number. To find average, you need to parse each line of number into real Number, Double.parseDouble("21.2") etc, and in each iteration, you know what to do :-)
For example:
double sum= 0;
int count = 0;
while(line != null) { // iterate over each line
lineCut = line.replaceAll(";" , ","); // replace ; with ,
//lineCut = line.substring(1, line.length());
int num = Double.parseDouble(lineCut);
sum = sum + num; count++;
bw.write(lineCut); // write each line to output file
bw.write("\n"); // print each line on a new line
line = br.readLine();
}
br.write(String.valueOf(sum/count));
Not tested. I am considering each line has a number and nothing else. Remember your should check the valou on linecount to avoid an Exception during the conversion from String to float.
public static void Write() throws Exception {
String line, lineCut;
BufferedReader br = null; //initialise BR- reads text from file
BufferedWriter bw = null; //initialise BR- writes text to file
try
{
br = new BufferedReader(new FileReader("/Users/jbloggs/Documents/input.txt")); //input file
bw = new BufferedWriter(new FileWriter("/Users/jbloggs/Desktop/output.txt")); //output file
line = br.readLine(); // declare string equal to each line
float sum = 0;
int counter = 0;
while(line != null) { // iterate over each line
lineCut = line.replaceAll(";" , ",");
sum += Float.parseFloat(lineCut);
counter++;
bw.write(lineCut); // write each line to output file
bw.write("\n"); // print each line on a new line
line = br.readLine();
}
bw.write("Average = ");
bw.write(sum / counter);
bw.write("\n");
System.out.println("success"); //print if program works
br.close();
bw.close();
}
catch(Exception e){
throw(e); // throw exception
}
}
}
Related
I have program that has a section that requires me to read and append items to a txt file. I know how to do basic reading and appending but I am confused as to how I would read every 4th line in a txt file and then store it in a variable. Or even every alternate line.
Also, if there are double valued numbers, can I read it as a number and not a string?
To read say every fourth line from a text file you would read a line and update a counter. When the counter reaches 4, you save the line in a String variable. Something like this would do the job:
import java.io.*;
public class SkipLineReader {
public static void main(String[] args) throws IOException {
String line = "";
String savedLine = "";
int counter = 0;
FileInputStream fin = new FileInputStream("text_file.txt");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(fin));
// Save every fourth line
while( (line = bufIn.readLine()) != null) {
counter++;
if( counter == 4 ) {
savedLine = line;
System.out.println(line);
}
}
}
}
To save every alternate line, you would save the line every time the counter reaches two and then reset the counter back to zero. Like this:
// Save every alternate line
while( (line = bufIn.readLine()) != null) {
counter++;
if( counter % 2 == 0 ) {
counter = 0;
savedLine = line;
System.out.println(line);
}
}
As for reading doubles from a file, you could do it with a BufferedReader and then use Double's parseDouble(string) method to retrieve the double value, but a better method is to use the Scanner object in java.util. The constructor for this class will accept a FileInputStream and there is a nextDouble() method that you can use to read a double value.
Here's some code that illustrates using a Scanner object to grab double values from a String (to read from a file, supply a FileInputStream into the Scanner class's constructor):
import java.util.*;
public class ScannerDemo {
public static void main(String[] args) {
String s = "Hello World! 3 + 3.0 = 6 true";
// create a new scanner with the specified String Object
Scanner scanner = new Scanner(s);
// use US locale to be able to identify doubles in the string
scanner.useLocale(Locale.US);
// find the next double token and print it
// loop for the whole scanner
while (scanner.hasNext()) {
// if the next is a double, print found and the double
if (scanner.hasNextDouble()) {
System.out.println("Found :" + scanner.nextDouble());
}
// if a double is not found, print "Not Found" and the token
System.out.println("Not Found :" + scanner.next());
}
// close the scanner
scanner.close();
}
}
This is my code example.
public static void main(String[] args) throws Exception {
// Read file by BufferedReader line by line.
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader("test.txt"));
String line = reader.readLine();
while (line != null) {
line = line.trim();
System.out.println(line);
// Using regular expression to check line is valid number
if (!line.trim().equals("") && line.trim().matches("^\\d+||^\\d+(\\.)\\d+$")) {
double value = Double.valueOf(line.trim());
System.out.println(value);
} else {
String value = line.trim();
System.out.println(value);
}
// Read next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
So, my lecture powerpoint slides and even my book is not really doing a good job (for my understanding that is) of explaining how to use formulas from a text document, then when the code runs/compiles successfully it will create a "Results.txt" in the same folder.
These are the formulas in a notepad doc. Nothing to crazy, just a proof of concept
4 * 5 ..
3 / 4...
3 - 1..
2 + 3..
import java.io.*;
import java.util.*;
public class ReadFileLineByLine {
public static void main(String[] args) throws FileNotFoundException {
String line;
int numberOfLines = 3;
String[] textData = new String[numberOfLines];
int i;
for(i = 0; i < numberOfLines; i++){
textData[i] = textReader.readLine();
}
text.Reader.close();
return textData;
try {
File inputfile = new File(args[0]); //new File("formulas.txt")
Scanner input = new Scanner(new File("C:\Users\Frost\Documents\Question4"));
BuffredReader br = new BufferedReader(new FileReader("C:\Users\Frost\Documents\Question4"));
PrintWriter output = new PrintWriter("Results.txt");
while (input.hasNextLine()) {
line = input.nextLine();
System.out.println("read <" + line + ">"); // Display message to commandline
// Declare ArrayList of for storing tokenized formula from String line
double result = 0; // The variable to store result of the operation
// Determine the operator and calculate value of the result
System.out.println(formula.get(0) + ' ' + formula.get(1) + ' ' +
formula.get(2) + " = " + result); // Display result to command line
// Write result to file
}
// Need to close input and output files
}
catch (FileNotFoundException e) {
System.out.println("Error reading file named " + Formulas.txt);
}
}
}
Here's something to get you started. The //TODO: comments are where you need to build your logic. Be sure to change the file paths back to what you need. I changed them to a Temp location. Also change the messages printed as I just put something there as proof of concept. I tried to comment thoroughly but don't hesitate to ask questions.
import java.io.*;
import java.util.*;
public class ReadFileLineByLine {
public static void main(String[] args) throws FileNotFoundException {
String line = "";
//Declare Scanner and PrintWriter outside of try clause so they can be closed in finally clause
Scanner input = null;
PrintWriter output = null;
try {
//Instantiate input and output file
input = new Scanner(new File("C:\\Temp\\test.txt"));
output = new PrintWriter(new File("C:\\Temp\\Results.txt"));
//Loop through lines in input file
while (input.hasNextLine()) {
line = input.nextLine();
// Display message to commandline
System.out.println("read <" + line + ">");
// Populate ArrayList of tokenized formula from String line
//TODO:
// The variable to store result of the operation
double result = 0;
// Determine the operator and calculate value of the result
//TODO:
// Write result to file
output.println("Print result of " + line + " to Results.txt");
}
} catch (FileNotFoundException e) {
//Exception thrown, print message to console
System.out.println("File Not Found: " + e.getMessage());
} finally {
//close files in finally clause so it happens even if exception is thrown
//I also set to null as extra precaution
input.close();
input = null;
output.close();
output = null;
}
}
}
I am using BufferedReader in java to read characters from an input file. However, the output is unusual. In my code below, I first use scanner to show the contents of the file itself then I use BufferedReader to print each individual character:
import java.util.Scanner;
import java.io.*;
//import java.io.File;
public class Inputs
{
public static void main(String[] args)
{
System.out.println("Inputs");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
System.out.println(input);
// Open the file
File file = new File("Simple.java");
try {
Scanner fileIn = new Scanner(file);
while(fileIn.hasNext()){
System.out.println(fileIn.next());
}
fileIn.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("Simple.java");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
String character = Character.toString ((char) br.read());
System.out.println (character);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
Below is the output I get, the first tokens displayed are by the scanner but after the highlighted prentices its the BufferedReaders output. It prints 3 spaces then a closed curly bracket then -1 (end). What is the meaning of this?
In your code you are reading the line in while loop condition with br.readline(). Then in the loop body you are again reading the char using br.read(). So the first character in the each line is printed.
while ((strLine = br.readLine()) != null) {
// Print the content on the console
String character = Character.toString ((char) br.read());
System.out.println (character);
}
To fix there either use the method metioned by Halko Sajtarevic(But there each char is read as an integer and converted back to string) or simply eliminate reading the character second time and just print the string.
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
Your problem is that you are reading the BufferedReader line by line instead of character by character.
Try this version instead:
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("Simple.java");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//Read File Line By Line
char c;
while ((c = (char) br.read()) != (char) -1) {
// Print the content on the console
String character = Character.toString(c);
System.out.print(character);
}
//Close the input stream
in.close();
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
My goal is that I wish to read from a file with the name "input.txt", which has 10 lines of text, and then write 5 lines from the original into two other files with the names "test1.txt" and "test2.txt". I'm using the following code, but it is not working - please help me.
import java.util.Scanner;
import java.io.*;
public class main {
public static void main (String args[]) throws FileNotFoundException, IOException{
BufferedReader br = new BufferedReader (new FileReader("bin/input.txt"));
File file = new File("bin/test2.txt");
BufferedWriter writer = new BufferedWriter(new FileWriter("bin/test.txt"));
Scanner sc = new Scanner (br);
int i = 0;
while (sc.hasNextLine()){
sc.nextLine();
i++;
System.out.print(i);
int n = (i+1)/2;
System.out.print("\n"+n);
writer.write(sc.nextLine().toString());
writer.newLine();
if (n==5){
writer.close();
}
}
if (sc != null){
sc.close();
}
}
}
this will read from single file and splitting content into two file.
int count = 0;
BufferedReader br = null;
FileWriter fileWriter1 = new FileWriter("G:\\test1.txt");
FileWriter fileWriter2 = new FileWriter("G:\\test2.txt");
try {
String currentLine;
br = new BufferedReader(new FileReader("G:\\input.txt"));
while ((currentLine = br.readLine()) != null) {
count++;
if (count <= 5) {
fileWriter1.write(currentLine + "\n");
} else {
fileWriter2.write(currentLine + "\n");
}
}
} finally {
if (br != null) {
br.close();
}
fileWriter1.close();
fileWriter2.close();
}
Create two BufferedWriter instead of one with two files and then follow the below procedure:
count <- 0
while scanner hasNextLine
do
string line <- scanner's next Line
if (count > 4) {
writer2.write line
} else {
writer1.write line
}
count <- count + 1
done
finally close all three resources.
I'm trying to make a program that reads a line from the database.txt and writes an odd/even numbered lines to files 1.txt and 2.txt. F.e. 1st(odd) line of the database.txt goes to 1.txt and the 2nd(even) line of the database.txt goes goes to 2.txt
Here's the code I got so far:
import java.io.*;
import java.util.Scanner;
public class Main {
public Main(){
op(null);
}
public void op(String args[]){
try{
FileReader fr = new FileReader("database.txt");
BufferedReader reader = new BufferedReader(fr);
String line = reader.readLine();
Scanner scan = null;
int ln = 1;
String even = "2txt";
String odd = "1.txt";
while ((line=reader.readLine())!=null){
scan = new Scanner(line);
if(ln%2==0){
wtf(even, line);
}else{
wtf(odd, line);
}
ln++;
line=reader.readLine();
}
reader.close();
}
catch (FileNotFoundException e){
System.out.println("File not found");
}
catch (IOException e) {
System.out.println("Impossibru to read");
}
}
public void wtf(String filename, String ltw){
try
{
FileReader fr = new FileReader(filename);
BufferedReader reader = new BufferedReader(fr);
String line = reader.readLine();
FileWriter writer = new FileWriter(filename);
BufferedWriter bw = new BufferedWriter(writer);
while(line==null){
bw.write(ltw);
bw.newLine();
}
bw.close();
}
catch ( IOException e)
{
}
}
}
At the moment its on an infinite loop reads only the 2nd line and spams it to 1.txt
Within the:
if(ln%2==0)
block you also need to add ln++;
Also move the
line=reader.readLine();
to directly outside the else block.
As an alternative, this is a somewhat reworked method:
Remove all of the line=reader.readLine();s including the first.
Rewrite the loop as:
while ((line=reader.readLine())!=null){
if(ln%2==0){
wtf(even, line);
}else{
wtf(odd, line);
}
ln++;
}
You are not incrementing the line count.
while (line!=null){
scan = new Scanner(line);
if(ln%2==0){
wtf(even, line);
ln++;
}else{
wtf(odd, line);
ln++;
line=reader.readLine();
}
}
reader.close();
}
if(ln%2==0){
wtf(even, line);
}else{
wtf(odd, line);
} //<------------here ?
ln++;
line=reader.readLine();
// }
}
reader.close();
update:
while((line=reader.readLine())!=null){
*
*
*
line=reader.readLine() ; //is this line required ?
update:
Check this also in wtf()
while(line==null){
bw.write(ltw);
bw.newLine();
}
The problem was with the wtf method. Your endless loop was in there when you wrote:
while(line==null){
bw.write(ltw);
bw.newLine();
}
BufferedReader states it returns null if the end of the stream has been reached. Since your files are initially empty (I'm assuming), this will constantly be true, and you will continue writing new lines and your String.
I was playing around with your code and rewrote it to something like this.
import java.util.*;
import java.io.*;
public class fread {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
String even = "2.txt";
String odd = "1.txt";
String line = "";
int lineNumber = 0;
while (scan.hasNext() )
{
line = scan.nextLine();
if (lineNumber++ % 2 == 1)
writeText(even, line);
else
writeText(odd, line);
}
}
static void writeText(String filename, String ltw)
{
try
{
BufferedWriter bw = new BufferedWriter(new FileWriter(filename, true));
bw.write(ltw);
bw.newLine();
bw.close();
}
catch ( IOException e)
{
e.printStackTrace();
}
}
}
It uses input redirection, so typing java fread < database.txt will give you your results, however this only does appends to a file. If your files do not exist, or are initially empty, this will work as you expect. You'll have to specify this code to the needs of the program. Regardless, you should be able to take my writeText method and incorporate it into your program to be able to to get yours working.
Your infinite loop is happening here:
if(ln%2==0)
wtf(even, line);
ln starts at 0. 0 % X = 0, therefore it is always considered an even number, and you just keep spamming out to the same line. Add the increment to your even clause.
Interesting side note
You have another infinite loop, because if the value is even, or 0, then you never read the next line.
Solution
if(ln%2==0){
wtf(even, line);
ln ++;
line = reader.readline();