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();
}
}
Related
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
}
}
}
I have the following code which tries to determine the dimensions of a file, but each time it executes through there is this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
I'm unaware why this is occurring. Can anyone help debug the issue? And explain why it is happening?
public void loadDistances(String fname) throws Exception {
String file = fname;
File f = new File(file);
Scanner in = null;
try {
in = new Scanner(f);
}
catch (FileNotFoundException ex) {
System.out.println("Can't find file " + file);
System.exit(1);
}
int rows = 0;
int cols = 0;
int elements = 0;
while(in.hasNext()){
while(in.next() != null){
System.out.println(elements++);
}
in.nextLine();
rows++;
}
in.close();
cols = (elements + 1) / rows;
// for debug purposes
System.out.println(rows);
System.out.println(cols);
}
Which reads in this file
0 2 3.0
1 0 2.0
2 1 7.0
2 3 1.0
3 0 6.0
// Checking for suggested answer
int tokens = 0;
String line;
Scanner tokenScanner;
Scanner fileScanner;
Scanner lineScanner;
while(fileScanner.hasNextLine()){
line = fileScanner.nextLine();
lineScanner.nextLine() = line;
while(lineScanner.hasNext()){
tokens++;
}
rows++;
}
You assign no data to your variables at all in your scanning loop, and not only that, but you read from the Scanner twice while checking it for data only once, a dangerous thing to do.
while(in.hasNext()){ // **** checking once ****
while(in.next() != null){ // **** read in and waste a token here!
System.out.println(elements++);
}
in.nextLine(); // **** read in and waste a line here
rows++;
}
in.close();
I would:
Use two Scanner variables, one, fileScanner, to read in each line of text in the file,...
And one called lineScanner to read in each token on the line.
I'd use an outer while loop, that checks fileScanner.hasNextLine(), and then calls nextLine() to read the line into a String, say called line.
I'd then create a new Scanner with the line of String created, and assign it into a lineScanner variable.
I'd use an inner while loop that loops while lineScanner.hasNext(), and reads in the data into your your variables.
I'd close the inner lineScanner at the end of the outer while loop so as not to waste resources.
Alternatively, you could use String#split(...) to split the tokens in the line read in, and then parse the Strings into numbers. For example,
public List<RowData> loadDistances(String fname)
throws FileNotFoundException, NumberFormatException {
File file = new File(fname);
Scanner fileScanner = new Scanner(file);
List<RowData> rowList = new ArrayList<RowData>();
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
String[] tokens = line.split("\\s+");
if (tokens.length != 3) {
// throw some custom exception
}
int rowNumber = Integer.parseInt(tokens[0].trim());
int xData = Integer.parseInt(tokens[1].trim());
double yData = Double.parseDouble(tokens[2].trim());
rowList.add(new RowData(rowNumber, xData, yData));
}
if (fileScanner != null) {
fileScanner.close();
}
return rowList;
}
Edit
By using a line Scanner, I recommend creating a second Scanner, passing in the line obtained from the first Scanner, and extracting data from this second Scanner. You could use a while loop if you didn't know how many tokens to expect, but your data appears to be well defined, with each line holding an int, int, and double, and we can use this information to help us extract the proper data. You could use code something like this:
// use previous same code as above except in the while loop:
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine(); // get line
Scanner lineScanner = new Scanner(line); // create Scanner with it
int rowNumber = 0;
int xData = 0;
double yData = 0.0;
if (lineScanner.hasNextInt()) {
rowNumber = lineScanner.nextInt();
} else {
// throw a custom exception since int not found
}
if (lineScanner.hasNextInt()) {
xData = lineScanner.nextInt();
} else {
// throw a custom exception since int not found
}
if (lineScanner.hasNextDouble()) {
yData = lineScanner.nextDouble();
} else {
// throw a custom exception since double not found
}
rowList.add(new RowData(rowNumber, xData, yData));
if (lineScanner != null) {
lineScanner.close();
}
}
I have a file that contain 100 line
each line contain one tag
I need to obtain the tag value given its rank which is the "id" of TagVertex Class
public abstract class Vertex <T>{
String vertexId ;// example Tag1
T vertexValue ;
public abstract T computeVertexValue();
}
public class TagVertex extends Vertex<String> {
#Override
public String computeVertexValue() {
// How to get the String from my file?
return null;
}
T try this but it doesnt work
public static void main(String args[]) {
File source //
int i=90;
int j=0;
String s = null;
try {
Scanner scanner = new Scanner(source);
while (scanner.hasNextLine()) {
if (j==i) s= scanner.nextLine();
else j++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s);
}}
Although there is a way to skip characters with BufferedReader, I don't think there's is a built-in way to skip whole lines.
BufferedReader bf = new BufferedReader(new FileReader("MyFile.txt"));
for(int i = 1; i < myVertex.vertexId; i++){
bf.readLine();
}
String n = bf.readLine();
if(n != null){
System.out.println(n);
}
I think there may be a better idea though.
This is command u can use to read from file:
BufferedReader bf = new BufferedReader(new FileReader("filename"));
This will read the file to the buffer.
Now, for reading each line u should use a while loop and read each line into string.
Like:
String str;
while((str = bf.readLine()) != null){
//handle each line untill the end of file which will be null and quit the loop
}
I'm trying to read in from whats on the first two lines of a txt file, put it on a string and pass that string onto my methods. I'm confused on what I need to do in the main method.
Heres what I have:
public class TestingClass {
Stacked s;// = new Stacked(100);
String Finame;
public TestingClass(Stacked stack) {
//Stacked s = new Stacked(100);
s = stack;
getFileName();
readFileContents();
}
public void readFileContents() {
boolean looping;
DataInputStream in;
String line = "" ;
int j, len;
char ch;
try {
in = new DataInputStream(new FileInputStream(Finame));
len = line.length();
for(j = 0; j<len; j++) {
System.out.println("line["+j+"] = "+line.charAt(j));
}
}
catch(IOException e) {
System.out.println("error " + e);
}
}
public void getFileName() {
Scanner in = new Scanner(System.in);
System.out.println("Enter File Name");
Finame = in.nextLine();
System.out.println("You Entered " + Finame);
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
TestingClass clas = new TestingClass(st);
//String y = new String("(z * j)/(b * 8) ^2");
// clas.test(y);
}
I tried String x = new String(x.getNewFile()) I'm not sure if thats the right way to go with that or not.
Try this:
File file = new File("file.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line1 = reader.readLine();
String line2 = reader.readLine();
It's even easier in Java 1.5+. Use the Scanner class. Here's an example. Essentially, it boils down to:
import java.io.*;
import java.util.Scanner;
public static void main(String... aArgs) throws FileNotFoundException {
String fileName = "MYFILE HERE";
String line = "";
Scanner scanner = new Scanner(new FileReader(fileName));
try {
//first use a Scanner to get each line
while ( scanner.hasNextLine() ){
line = scanner.nextLine();
}
}
finally {
//ensure the underlying stream is always closed
//this only has any effect if the item passed to the Scanner
//constructor implements Closeable (which it does in this case).
scanner.close();
}
}
...so there's really no reason for you to have a getFileContents() method. Just use Scanner.
Also, the entire program flow could use some restructuring.
Don't declare a Stacked inside of your main method. It's likely
that's what your testing class should encapsulate.
Instead, write a private static String method to read the file name from the keyboard, then pass that to to your TestingClass object.
Your TestingClass constructor should call a private method that opens
that file, and reads in the first 2 (or however many else you end up
wanting) lines into private class variables.
Afterwards you can instantiate a new Stacked class.
For good encapsulation principles, have your TestClass provide public methods that the Driver program (the class with the public static void main() method can call to access the Stacked instance data without allowing access to the Stacked object directly (hence violating the Law of Demeter).
Likely this advice will seem a little hazy right now, but get in the habit of doing this and in time you'll find yourself writing better programs than your peers.
Reading from a txt file is usually pretty straightforward.
You should use a BufferedReader since you want the first two lines only.
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
linecount = 0;
StringBuilder myline = new StringBuilder();
String line = "";
while ( (linecount < 2) && ((line = br.readLine()) != null) ) {
myline.append(line);
linecount++;
}
// now you have two lines in myline. close readers/streams etc
return myline.toString();
You should change your method signature to return the string. Now, you can say
String x = clas.getFileContent();
//-------------------------------------------------------------------------
//read in local file:
String content = "";
try {
BufferedReader reader = new BufferedReader(new FileReader(mVideoXmlPath));
do {
String line;
line = reader.readLine();
if (line == null) {
break;
}
content += line;
}
while (true);
}
catch (Exception e) {
e.printStackTrace();
}
check this :=)
So this is what I have so far :
public String[] findStudentInfo(String studentNumber) {
Student student = new Student();
Scanner scanner = new Scanner("Student.txt");
// Find the line that contains student Id
// If not found keep on going through the file
// If it finds it stop
// Call parseStudentInfoFromLine get the number of courses
// Create an array (lines) of size of the number of courses plus one
// assign the line that the student Id was found to the first index value of the array
//assign each next line to the following index of the array up to the amount of classes - 1
// return string array
}
I know how to find if a file contains the string I am trying to find but I don't know how to retrieve the whole line that its in.
This is my first time posting so If I have done anything wrong please let me know.
You can do something like this:
File file = new File("Student.txt");
try {
Scanner scanner = new Scanner(file);
//now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if(<some condition is met for the line>) {
System.out.println("ho hum, i found it on line " +lineNum);
}
}
} catch(FileNotFoundException e) {
//handle this
}
Using the Apache Commons IO API https://commons.apache.org/proper/commons-io/ I was able to establish this using FileUtils.readFileToString(file).contains(stringToFind)
The documentation for this function is at https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/FileUtils.html#readFileToString(java.io.File)
Here is a java 8 method to find a string in a text file:
for (String toFindUrl : urlsToTest) {
streamService(toFindUrl);
}
private void streamService(String item) {
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.filter(lines -> lines.contains(item))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
When you are reading the file, have you considered reading it line by line? This would allow you to check if your line contains the file as your are reading, and you could then perform whatever logic you needed based on that?
Scanner scanner = new Scanner("Student.txt");
String currentLine;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Perform logic
}
}
You could use a variable to hold the line number, or you could also have a boolean indicating if you have passed the line that contains your string:
Scanner scanner = new Scanner("Student.txt");
String currentLine;
int lineNumber = 0;
Boolean passedLine = false;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Do task
passedLine = true;
}
if(passedLine)
{
//Do other task after passing the line.
}
lineNumber++;
}
This will find "Mark Sagal" in Student.txt. Assuming Student.txt contains
Student.txt
Amir Amiri
Mark Sagal
Juan Delacruz
Main.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
final String file = "Student.txt";
String line = null;
ArrayList<String> fileContents = new ArrayList<>();
try {
FileReader fReader = new FileReader(file);
BufferedReader fileBuff = new BufferedReader(fReader);
while ((line = fileBuff.readLine()) != null) {
fileContents.add(line);
}
fileBuff.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(fileContents.contains("Mark Sagal"));
}
}
I am doing something similar but in C++. What you need to do is read the lines in one at a time and parse them (go over the words one by one). I have an outter loop that goes over all the lines and inside that is another loop that goes over all the words. Once the word you need is found, just exit the loop and return a counter or whatever you want.
This is my code. It basically parses out all the words and adds them to the "index". The line that word was in is then added to a vector and used to reference the line (contains the name of the file, the entire line and the line number) from the indexed words.
ifstream txtFile;
txtFile.open(path, ifstream::in);
char line[200];
//if path is valid AND is not already in the list then add it
if(txtFile.is_open() && (find(textFilePaths.begin(), textFilePaths.end(), path) == textFilePaths.end())) //the path is valid
{
//Add the path to the list of file paths
textFilePaths.push_back(path);
int lineNumber = 1;
while(!txtFile.eof())
{
txtFile.getline(line, 200);
Line * ln = new Line(line, path, lineNumber);
lineNumber++;
myList.push_back(ln);
vector<string> words = lineParser(ln);
for(unsigned int i = 0; i < words.size(); i++)
{
index->addWord(words[i], ln);
}
}
result = true;
}
Here is the code of TextScanner
public class TextScanner {
private static void readFile(String fileName) {
try {
File file = new File("/opt/pol/data22/ds_data118/0001/0025090290/2014/12/12/0029057983.ds");
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("usage: java TextScanner1"
+ "file location");
System.exit(0);
}
readFile(args[0]);
}
}
It will print text with delimeters