I'm new to Java and I have to read from a file, and then convert what I have read into variables. My file consists of a fruit, then a price and it has a long list of this. The file looks like this:
Bananas,4
Apples,5
Strawberry,8
...
Kiwi,3
So far I have created two variables(double price and String name), then set up a scanner that reads from the file.
public void read_file(){
try{
fruits = new Scanner(new File("fruits.txt"));
print_file();
}
catch(Exception e){
System.out.printf("Could not find file\n");
}
}
public void print_file(){
while(fruits.hasNextLine()){
String a = fruits.nextLine();
System.out.printf("%s\n", a);
return;
}
}
Currently I am only able to print out the entire line. But I was wondering how I could break this up to be able to store the lines into variables.
So your string a has an entire line like Apples,5. So try to split it by comma and store it into variables.
String arr[] = a.split(",");
String name = arr[0];
int number = Integer.parseInt(arr[1]);
Or if prices are not integers, then,
double number = Double.parseDouble(arr[1]);
Using java 8 stream and improved file reading capabilities you can do it as follows. it stores item and count as key value pair in a map. It is easy to access by key afterwards.
I know this Maybe too advance but eventually this will help you later when getting to know new stuff in java.
try (Stream<String> stream = Files.lines(Paths.get("src/test/resources/items.txt"))) {
Map<String, Integer> itemMap = stream.map(s -> s.split(","))
.collect(toMap(a -> a[0], a -> Integer.valueOf(a[1])));
System.out.println(itemMap);
} catch (IOException e) {
e.printStackTrace();
}
output
{Apples=5, Kiwi=3, Bananas=4, Strawberry=8}
You can specify a delimiter for the scanner by calling the useDelimiter method, like:
public static void main(String[] args) {
String str = "Bananas,4\n" + "Apples,5\n" + "Strawberry,8\n";
try (Scanner sc = new Scanner(str).useDelimiter(",|\n")) {
while (sc.hasNext()) {
String fruit = sc.next();
int price = sc.nextInt();
System.out.printf("%s,%d\n", fruit, price);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(
"C://Test/myfile.txt")); //Your file location
String line = reader.readLine(); //reading the line
while(line!=null){
if(line!=null && line.contains(",")){
String[] data = line.split(",");
System.out.println("Fruit:: "+data[0]+" Count:: "+Integer.parseInt(data[1]));
}
//going over to next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
I have a problem and wanted to ask if someone can help me. I have a Java application that processes CSV files. The files have a semi-colon as a "delimiter". Now instead of semicolons I would like to use pipe "|" as the "delimiter". What is the best way to do this?
I have already informed myself in the library or class "org.apache.commons.csv.CSVRecord". Unfortunately couldn't find anything here.
I used for parsing Spring Batch with the class FlatItemReaderBuilder.
You can also use Spring Batch classes in non Spring application.
Here you can find an example:
https://www.petrikainulainen.net/programming/spring-framework/spring-batch-tutorial-reading-information-from-a-file/
you could use Scanner or FileInputStream
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ReadDelimited {
public static void main(String[] args) {
Scanner sc = null;
try {
sc = new Scanner(new File("D:\\acct.csv"));
// Check if there is another line of input
while(sc.hasNextLine()){
String str = sc.nextLine();
// parse each line using delimiter
parseData(str);
}
} catch (IOException exp) {
// TODO Auto-generated catch block
exp.printStackTrace();
}finally{
if(sc != null)
sc.close();
}
}
private static void parseData(String str){
String acctFrom, acctTo, amount;
Scanner lineScanner = new Scanner(str);
lineScanner.useDelimiter("|");
while(lineScanner.hasNext()){
acctFrom = lineScanner.next();
acctTo = lineScanner.next();
amount = lineScanner.next();
System.out.println("Account From- " + acctFrom + " Account To- " + acctTo +
" Amount- " + amount);
}
lineScanner.close();
}
}
reference Code original link
or if File is not too large get the read the File in a string Divide it into a String array by splitting by line break and then future splitting using the delimiter of choice something like the code below.
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream=new FileInputStream("j:\\test.csv");
String s1=new String(fileInputStream.readAllBytes());
String[] lineArray=s1.split("\n");
List<String[]> separatedValues=new ArrayList<>();
for (String line: lineArray) {
separatedValues.add(line.split("\\|"));
}
for (String[] s: separatedValues) {
for (String s2:s ) {
System.out.print(s2+" ");
}
System.out.println("");
}
fileInputStream.close();
}
Code Output Link
Original CSV
I am a begginer(recently began learning) at programming in Java and I need help.
I have to read from a file, which contains numbers. I would like to make a method for reading from a file. Then I need to analyze this data and write it in another file.
What I strugle with is if I make a method just to read from a file or do I also have to save this read data into a variable. Where should this variable be declared inside a method (if is inside, how do I use it outside), if is outside how do I use it inside a method and also outside. Can anyone help me clarify this? What am I doing wrong?
My code of what I wrote until now. File from which I had to read has houndreds of numbers.
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
File file = new File(nameFile);
String contentFile ="";
}
//Method for reading a .txt file
private static String readFromFile(String nameFile, String contentFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
while((line = read.readLine()) != null) {
line = contentFIle;
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
}
Theoretically speaking: mathematical functions get input variables, they preform some transformation on the variables and output the result of the transformation.
For example: f(x) = x - 1, g(x) = x * 2
You can chain functions in a way that one functions output will be the other function input: g(f(2)). In this case, the number 2 is used as an input for function f(x) and the output of f(x) is the input of g(x).
Functions and methods in programming can work in a similar way, but It may be more readable to save function output into meaningful variable names, and then to apply these variables to the next function.
Instead of doing: outputText(processText(readText(someFilename)))
You can write (pseudocode):
someFilename = 'foo'
text = readText(someFilename)
processed = processText(text)
outputText(processed)
In java and in your context this would look like the following:
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFileByName(nameFile);
String altered = processText(contentFile);
saveToFile(altered, "processed.txt");
}
private static String readFromFileByName(String nameFile) {
String fullRead = "";
try {
File file = new File(nameFile);
BufferedReader read = new BufferedReader(new FileReader(file));
String line; // define line variable
while((line = read.readLine()) != null) {
fullRead += line; // pay attention for the altered code
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
} finally {
return fullRead;
}
}
private static List<Integer> stringToIntList(String string) {
return Arrays
.stream(text.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
}
private static String processText(String text) {
String processed = text.replace('H', 'h'); // Some heavy processing :)
return processed;
}
private static void saveToFile(String text, String fileName) {
// save <text> to file with filename <filename>
}
}
1) Line is the variable that you have read to. So you shouldn't change its value.
line = contentFIle;
if you need only first line this method should look like:
private static String readFromFile(String nameFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
line = read.readLine();
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
if you need a list of this:
List<String> lines = Collections.emptyList();
try {
Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
} catch (IOException e) {
// do something
e.printStackTrace();
}
return lines;
2) Also you don't call readFromFile function. So you need to change the main method:
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFile(nameFile);
}
3)For your particular case, there's no sense to call readFromFile with String contentFile because you don't use this variable.
My method read and prints the file, but I am having trouble adding each word to the ArrayList dict.
The reader reads the file one char at a time, so what I have written adds each char to dict: [c,a,t,d,o,g] when I want [cat,dog]. The text file has the words on their own line; how can I distinguish them?
My code so far:
public static List Dictionary() {
ArrayList <String> dict = new ArrayList <String>();
File inFile = new File("C:/Users/Aidan/Desktop/fua.txt");
FileReader ins = null;
try {
ins = new FileReader(inFile);
int ch;
while ((ch = ins.read()) != -1) {
System.out.print((char) ch);
dict.add((char) ch + "");
}
} catch (Exception e) {
System.out.println(e);
} finally {
try {
ins.close();
} catch (Exception e) {
}
}
return dict;
}
Please observe Java naming conventions, so readDictionary instead of Dictionary (which looks like a class name). Next, I would pass the fileName into the method (instead of hard-coding the path in your method). Instead of reinventing the wheel, I would use a Scanner. You can also use the try-with-resources instead of finally here (and the diamond operator). Like,
public static List<String> readDictionary(String fileName) {
List<String> dict = new ArrayList<>();
try (Scanner scan = new Scanner(new File(fileName))) {
while (scan.hasNext()) {
dict.add(scan.next());
}
} catch (Exception e) {
System.out.printf("Caught Exception: %s%n", e.getMessage());
e.printStackTrace();
}
return dict;
}
Alternatively, use a BufferedReader and split each word yourself. Like,
public static List<String> readDictionary(String fileName) {
List<String> dict = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(
new File(fileName)))) {
String line;
while ((line = br.readLine()) != null) {
if (!line.isEmpty()) {
Stream.of(line.split("\\s+"))
.forEachOrdered(word -> dict.add(word));
}
}
} catch (Exception e) {
System.out.printf("Caught Exception: %s%n", e.getMessage());
e.printStackTrace();
}
return dict;
}
But that is basically what the first example does.
Check out the answer here which shows how to use Scanner to get words from a file: Read next word in java.
Instead of printing out the words, you'd want to append them to an ArrayList.
As the read method of the FileReader can only read a single character at a time and that's not what you want, then I would suggest you use a Scanner to read the file.
ArrayList<String> dict = new ArrayList<>();
Scanner scanner = new Scanner(new File("C:/Users/Aidan/Desktop/fua.txt"));
while(scanner.hasNext()){
dict.add(scanner.next());
}
You can wrap your FileReader in a BufferedReader, which has a readLine() method that will get you an entire line (word) at a time. readLine() returns null when there are no more lines to read.
I have to write code that will reverse the order of the string and write it in a new file. For example :
Hi my name is Bob.
I am ten years old.
The reversed will be :
I am ten years old.
Hi my name is Bob.
This is what I have so far. Not sure what to write for the outWriter print statement. Any help will be appreciated. Thanks!
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class FileRewinder {
public static void main(String[] args) {
File inputFile = new File("ascii.txt");
ArrayList<String> list1 = new ArrayList<String>();
Scanner inputScanner;
try {
inputScanner = new Scanner(inputFile);
} catch (FileNotFoundException f) {
System.out.println("File not found :" + f);
return;
}
while (inputScanner.hasNextLine()) {
String curLine = inputScanner .nextLine();
System.out.println(curLine );
}
inputScanner.close();
File outputFile = new File("hi.txt");
PrintWriter outWriter = null;
try {
outWriter = new PrintWriter(outputFile);
} catch (FileNotFoundException e) {
System.out.println("File not found :" + e);
return;
}
outWriter.println(???);
outWriter.close();
}
}
My suggestion is read entire file first and store sentences(you can split by .) in a LinkedList<String>(this will keep insertion order)
Then use Iterator and get sentences in reverse order. and write them into a file. make sure to put . just after each sentence.
After System.out.println(curLine ); add list1.add(curline); that will place your lines of text into your list.
At the end create a loop over list1 backwards:
for(int i = list1.size() - 1 , i > 0, --i) {
outWriter.println(list1[i]);
}
If the file contains an amount of lines which can be loaded into the memory. You can read all lines into a list, reverse the order of the list and write the list back to the disk.
public class Reverse {
static final Charset FILE_ENCODING = StandardCharsets.UTF_8;
public static void main(String[] args) throws IOException {
List<String> inLines = Files.readAllLines(Paths.get("ascii.txt"), FILE_ENCODING);
Collections.reverse(inLines);
Files.write(Paths.get("hi.txt"), inLines, FILE_ENCODING);
}
}
I am trying to add objects to a queue from a data file which is made up of text which is made up of a person's first name and their 6 quiz grades (ie: Jimmy,100,100,100,100,100,100). I am accessing the data file using the FileReader and using BufferReader to read each line of my data file and then tokenize each line using the "," deliminator to divide the names and quiz grades up. Based on what I think my professor is asking for is to create a queue object for each student. The assignment says,
Read the contents of the text file one line at a time using a loop. In this loop, invoke the processInputData method for each line read. This method returns the corresponding Student object. Add this student object to the studentQueue.
If someone could point me the right direction that would be great! Here is my code so far:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Test {
public static void main(String[] args) {
// Create an empty queue of student objects
LinkedList<Student> studentQueue;
studentQueue = new LinkedList<Student>();
// Create an empty map of Student objects
HashMap<String, Student> studentMap = new HashMap<String, Student>();
System.out.printf("Initial size = %d\n", studentMap.size());
// Open and read text file
String inputFileName = "data.txt";
FileReader fileReader = null;
// Create the FileReader object
try {
fileReader = new FileReader(inputFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// BufferReader to read text file
BufferedReader reader = new BufferedReader(fileReader);
String input;
// Read one line at a time until end of file
try {
input = reader.readLine();
while (input != null) {
processInputData(input);
input = reader.readLine();
}
}
catch (IOException e) {
e.printStackTrace();
}
// Close the input
try {
fileReader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
// Tokenize the data using the "," as a delimiter
private static void processInputData(String data) {
StringTokenizer st = new StringTokenizer(data, ",");
String name = st.nextToken();
String homework1 = st.nextToken();
String homework2 = st.nextToken();
String homework3 = st.nextToken();
String homework4 = st.nextToken();
String homework5 = st.nextToken();
String homework6 = st.nextToken();
// Using the set methods to correspond to the Student object
Student currentStudent = new Student(name);
currentStudent.setHomework1(Integer.parseInt(homework1));
currentStudent.setHomework2(Integer.parseInt(homework2));
currentStudent.setHomework3(Integer.parseInt(homework3));
currentStudent.setHomework4(Integer.parseInt(homework4));
currentStudent.setHomework5(Integer.parseInt(homework5));
currentStudent.setHomework6(Integer.parseInt(homework6));
System.out.println("Input File Processing...");
System.out.println(currentStudent);
}
}
One possible solution to your problem is returning the student in processInputData(..)
private static Student processInputData(String data) {
// the same code
return currentStudent;
}
And in while loop
while (input != null) {
studentQueue.add(processInputData(input));
input = reader.readLine();
}
Also try to manage better your try-catch blocks, cause if your fileReader throws exception then the code will continue running and throw probably a nullPointerException that you don't handle.
try{
fileReader = new FileReader(inputFileName);
BufferedReader reader = new BufferedReader(fileReader);
}catch(IOException ex){
//handle exception;
}finally{
// close resources
}