Reading and Saving .txt files into an array in Java - java

I am currently trying to figure out how to read and save .txt files to a dynamic array in Java, I do not know how to save the read .txt file into the array. The file I am trying to read is named songCollection.txt.
The specific data parts need to be:
title,artist,genre,album,songID
Below is my current code, any help will be much appreciated. Thanks
Code:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.io.*;
public class song {
private int SongID; // The unique song identifier
private String title; // The song title
private String artist; // The song artist
private String genre; // The genre of the song
private String album; // The album name
private String songData;
public song() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream fstream = new FileInputStream("songCollection.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
Readable fileSong;
String[] songData = new Scanner(fileSong);
while (songData.hasNextLine()) {
String songCollection = songData.nextLine();
songData = songCollection.split(",");
}
}
}

I am not sure what exactly you are looking. But if you are simply looking to store data in then you can store string array in ArrayList or any collection that suits you.
If you want to use it later for fast retrieval you can use any of the map implementation to store the key and value pair

Question: "I do not know how to save the read .txt file into the array"
Answer:
Most text files can be read into your program using a simple Scanner. For example:
Scanner input = new Scanner(fileName);
int[] ints = new int[10];
int i = 0;
while (input.hasNextInt()) {
input.nextInt() = ints[i];
i++
}
input.close()
The only issue with your approch is that you don't know how big of an array you will need. I recommend you store your input in a data structure that dynamically allocates space, like a LinkedList or an UnboundedStack.

Instead of printing out tokens to console you should create a new Song instance and set values to it:
song s = new song();
s.SongId = Integer.parseInt(splitOut[0]);
s.title = splitOut[1];
s.artist = splitOut[2];
...
And then put this song instance to a list.
Also consider implementing Song constructor with all these fields as arguments.

String temp = "";
try{
Scanner input = new Scanner("yourfile.txt");
while(input.hasNext()){
temp = temp + "_" + input.next();
}
input.close();
}
catch(Exception e){
}
String fin[] = temp.split("_");

You should define the constructor of your Song class as:
public Song(int songId, String title, String artist, String genre,
String album, String songData) {
this.songId = songId;
this.title = title;
this.artist = artist;
this.genre = genre;
this.album = album;
this.songData = songData;
}
And here's an example of using BufferedReader to read all song lines into a list (this code requires Java7):
List<Song> songs = new ArrayList<>(); // List of Song objects
try (BufferedReader input = new BufferedReader(new InputStreamReader(
new FileInputStream("songCollection.txt"), Charset.forName("UTF-8")))) {
String line;
while ((line = input.readLine()) != null) {
String[] arr = line.split(",");
songs.add(new Song(Integer.parseInt(arr[0]), arr[1], arr[2], arr[3],
arr[4], arr[5])); // <- Add new Song to list.
}
} catch (IOException e) {
e.printStackTrace();
}
Live example: http://ideone.com/HFn4jY

Related

Split multi line delimiter

Trying to split a text file which contains information about an album that has different formatting. Each album is divided by the dashed line with the first line of each section containing information about the album which is separated by colons and the lines after are the tracks in the album.
1:Whatever People Say I Am That's What I'm Not:Arctic Monkeys:2006:1.95M
The View from the Afternoon (3:38)
I Bet You Look Good on the Dancefloor (2:53)
----------------------------------------------------------------------------------
2:Different Class:Pulp:1996:1.33M
Mis-Shapes (3:46)
Pencil Skirt (3:11)
----------------------------------------------------------------------------------
20:Konnichiwa:Skepta:2016:207K
Konnichiwa (3:16)
Lyrics (2:36)
----------------------------------------------------------------------------------
I need help to split this into an album object. I've made the album class :
//Album attributes
private String salesRanking;
private String title;
private String artistName;
private String yearRelease;
private String sales;
private String [] tracks; //Array of string to store each track in album
//Album object constructor
public Album (String salesRanking, String title, String artistName, String yearRelease, String sales, String [] tracks){
this.salesRanking = salesRanking;
this.title = title;
this.artistName = artistName;
this.yearRelease = yearRelease;
this.sales = sales;
this.tracks = tracks;
}
To split the text file and put the content into the album object is where I'm having issues. I've tried
//Store album objects
ArrayList <String []> bulkAlbum = new ArrayList<>();
try{
//Read file
FileReader freader = new FileReader(albumData);
BufferedReader breader = new BufferedReader(freader);
String line;
while((line=breader.readLine()) != null ){
//Removes empty array
if(line.startsWith("-")){
continue;
}
//Split each album entry
String [] albumDetail = line.split("-");
bulkAlbum.add(albumDetail);
line = "";
}
breader.close();
freader.close();
} catch(IOException ex) {
System.out.println(ex);
}
When I run the code the output shows each line as an array of it's own in the arrayList, I realise the mistake I made is because it's only reading line by line but I don't know where to go from here so that the text file is read whole then split or split as chunks by the dashed line to create the album object.
Concatenating the lines then using ":" to split wont work because of the colon in the time.
I've been thinking about the logic but don't know what else to try.
EDIT - Finally solved this with the help of : How to split text file into objects java
You can try this -
Implementing the logic part of it assuming you'll take care of parsing and reading file.
static class Block {
String firstLine;
List<String> tracks;
public Block(String firstLine, List<String> tracks) {
this.firstLine = firstLine;
this.tracks = tracks;
}
}
public static void main(String[] args) {
List<Block> blocks = new ArrayList<>();
try{
//Read file
FileReader freader = new FileReader("../");
BufferedReader breader = new BufferedReader(freader);
List<String> lines = (List<String>) breader.lines();
int i = 0;
while(i < lines.size()){
List<String> addLines = new ArrayList<>();
if(lines.get(i).startsWith("-")){
i++;
} else {
while(!lines.get(i).startsWith("-")){
addLines.add(lines.get(i));
i++;
}
String firstLine = addLines.get(0);
addLines.remove(0);
Block block = new Block(firstLine,addLines);
blocks.add(block);
}
}
breader.close();
freader.close();
} catch(IOException ex) {
System.out.println(ex);
}
List<Album> albums = new ArrayList<>();
for (Block block: blocks) {
//Implement these Methods by yourself
parseFirstLine(block.firstLine);
parseListOfTracks(block.tracks);
}
}

I am stuck somewhere i couldn't find

I dont understand why i am not able to read from the file.I am always getting null with Readline() method of BufferedReader .
TestStudent class should be able to perform the following functions:
Create an ArrayList object of Student objects called studentList, using the student data stored in a text file named students.txt (you should create this file such that it stores the student name and ID of several students initially – one line per student)
Allow the user to add as many new Student objects as the user requests to the ArrayList ensuring that each student has a unique student ID
When the user has finished adding new students to the list, the program will override the students.txt file such that it includes the data relating to the new students as well as the original ones
Ability to display a full list of students as well as just the existing student IDs when necessary
Here's what i have done till now.
import java.util.*;
import java.io.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class TestStudent {
public static void main(String[] args) throws IOException {
File f=new File("C:\\Users\\user1\\Desktop\\Students.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
// FileReader reads text files in the default encoding.
FileReader fileReader =
new FileReader(f);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
//File f=new File("Student.txt");
Scanner sc=new Scanner(System.in);
Scanner scan = new Scanner(f);
ArrayList<Student> studentList = new ArrayList<>();
String cont;
do {
System.out.println("Enter Student Name:");
String name=sc.next();
System.out.println("Enter Student ID:");
String id=sc.next();
bw.write(name);
bw.write("\t"+id);
bw.newLine();
System.out.println("Continue Adding?");
cont=sc.next();
}
while(cont.equalsIgnoreCase("y"));
while(bufferedReader.readLine() != null){
String line = bufferedReader.readLine();
String[] record = line.split("\t");
Student myStudent =new Student(record[0],record[1]);
studentList.add(myStudent);
}
for(Student st:studentList)
System.out.println(st.Name+" "+st.Id);
bw.close();
scan.close();
sc.close();
}
}
class Student{
String Name, Id;
with default value red
Student(String string, String string0) {
System.out.println("s");
}
//Following are Mutators methos
public String getName() {
return this.Name;
}
public String getId() {
return this.Id;
}
//Following are accessor Methods
public void setName(String s){
this.Name=s;
}
public void setID(String ID) {
this.Id = ID;
}
public String toString() {
return "Student name is "+getName()+" Student Id is "+getId();
}
public boolean isValidID() {
if(getId().length()!=6)
return false;
else{
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return false;
}
return true;
}
}
public boolean IDExists(Student other) {
if(other.getId().equals(this.getId()))
return true;
else
return false;
}
}
The problem is here:
while(bufferedReader.readLine() != null){
String line = bufferedReader.readLine();
...
}
The first call to readLine() reads the line, but does not assign it - its lost. The next call to readLine() reads the next line.
It should be:
String line = null;
while ((line = bufferedReader.readLine()) != null){
....
}
This reads the next line, assign it to line, and then compares to null.
Then, your student constructor is broken:
Student(String string, String string0) {
System.out.println("s");
}
You never assign string and string0 to anything, and Id and Name are not assigned and always null.
Your code furthermore does not compile:
String Name, Id;
with default value red
This is a syntax error.
Read about How to create a Minimal, Complete, and Verifiable example to ensure your code is working and your question focused on one problem at a time. Most of your problems would be gone simply by making sure you test every part of your program separately and make sure it actually compiles.
you forgot to assign studentID and studentName for new Object in constructor
Student(String string, String string0) {
System.out.println("s");
id = string;
name = string0;
}
and because you write and read the same file so you must close fileWriter before reading
do {
// your code
}
while(cont.equalsIgnoreCase("y"));
// close buffer writer before reading
bw.close()
String line;
while((line = bufferedReader.readLine()) != null){
String[] record = line.split("\t");
Student myStudent =new Student(record[0],record[1]);
studentList.add(myStudent);
}

Creating objects via txt file into an array in Java

I am trying to complete a little program.
I've got a text file (.txt) to store different data on objects that i've got.
The structure of the file is the next (exemples data.txt) :
Sedane
2005
195000
Diesel
Blue
SUV
2013
34000
Fuel
Black
Each object is made true a class that i've build called Cars.
So the 1 line is the type of car, the 2nd the year of built, the 3rd line is the milage, the 4th is the type of fuel, and the 5th line is the color of the car.
So basicly i need to open the file, and load the data into the memory when i execute my program into an array with object in it.
I'm ok to open the file but i'm blocked when it comes to reading the data and putting it in an array.
The array size is 2 for this exemple, but if i have more entries in the file it's going to adapt it's size when loading at the startup of the program.
Here's what i've got unti now (for my code ...)
public static void loadCars () {
FileReader fopen;
BufferedReader opened;
String line;
try {
fEntree = new FileReader( "data.txt" );
opened = new BufferedReader( fopen );
while ( opened.ready() ) {
line = opened.readLine();
// Don't know what to do here ????
}
opened.close();
} catch ( IOException e ) {
System.out.println( "File doesn't exist !" );
}
}
Someting like this will do the trick. I'm adding the file contents line by line to an Arraylist instead of an array though. This way you don't have to know how big your array needs to be before hand. Plus you can always change it to an array later.
public ArrayList<String> readFileToMemory(String filepath)
{
in = new BufferedReader(new FileReader( "data.txt" ));
String currentLine = null;
ArrayList<String> fileContents = new ArrayList<String>();
try
{
while((currentLine = in.readLine()) != null)
{
fileContents.add(currentLine);
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
in.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
return fileContents;
}
LineNumberReader lnr = new LineNumberReader(new FileReader(new File("File1")));
lnr.skip(Long.MAX_VALUE);
long length = lnr.getLineNumber();
lnr.close();
in = new BufferedReader(new FileReader( "data.txt" ));
Car[] cars= new Car[length/5];
String currentLine;
int i=0;
for(int i=0;i<length/5;i+=5) {
String name = in.readLine();
String year = in.readLine();
String miles = in.readLine();
String gas = in.readLine();
String color = in.readLine();
cars[i] = new Car(name,year,miles,gas,color);
}
You'll have to handle exceptions too, surround stuff in try catch structures.
You can look at my solution here below (I also corrected/simplified some problems with the variables for reading the file, anyway this was not the main topic):
public static void loadCars() {
FileReader fopen;
BufferedReader opened;
String line;
ArrayList<Car> carList = new ArrayList<Car>();
try {
fopen = new FileReader("data.txt");
opened = new BufferedReader(fopen);
int nFields = 5; // we have 5 fields in the Car class
String[] fields = new String[nFields]; // to temporary store fields values read line by line
int lineCounter = 0;
while ((line = opened.readLine()) != null) {
fields[lineCounter] = line;
lineCounter++;
if ((lineCounter) % nFields == 0) { //it means we have all 5 fields values for a car
carList.add(new Car(fields)); //therefore we create a new car and we add it to the list of cars
}
}
opened.close();
} catch (IOException e) {
System.out.println("File doesn't exist !");
}
}
Basically we use an ArrayList to store all the cars, and we read the file, waiting to have all the fields values in order to create the Car object. I store the fields values in an array of Strings: I don't know how you implemented the Car class, but maybe it is useful to create a constructor that takes as parameter an array of strings, so it can set the fields, for instance:
class Car {
private String type;
private String year;
private String milage;
private String fuel;
private String color;
public Car(String[] fields) {
type=fields[0];
year=fields[0];
milage=fields[0];
fuel=fields[0];
type=fields[0];
}
}
But I've to say that probably this is a little 'too static'.
For simplicity I assumed that all your fields are of String type, but probably fields like 'year' or 'milage' might be of int type. In this case you can use array of Object[] (instead of String[]), and then cast the value with the right type.
I hope this may help you.

Using a loop I want to find the value of a column from my CSV file java

Forgive me if this is a basic (or not very well explained) question, I am fairly new to Java and have been reading extensive material as well as trying to understand the relevant Javadoc but to no avail.
To give a brief background as to what I am trying to create, I have created a reader class which reads data in from a csv file (4 lines long) including fields such as Item ID, price, description etc. I have created a separate demo class that displays the details of this csv file (through creating an instance of my reader class) and am now trying to create a method that asks the user to input an Item ID that then displays the corresponding Item, based on the ID input by the user. The part I am stuck on is accessing specific rows/columns in a csv file and then comparing these with a given string (entered by the user which corresponds to a specific field in the csv file)
This is what I have come up with thus far:
input = new Scanner(System.in);
System.out.println("Enter a product code");
String prodC = input.next();
//Here I want to know if there is a way of accessing a field in a csv file
Any ideas would be greatly appreciated.
UPDATE
Thank you for quick responses, am currently reading through and seeing how I can try to implement the various techniques. In response to the comment asking about the file reader, this is how I have set that out:
public CatalogueReader(String filename) throws FileNotFoundException {
this.filename = filename;
this.catalogue = new Catalogue();
Scanner csvFile;
try {
csvFile = new Scanner(new File(filename));
} catch (FileNotFoundException fnf) {
throw new FileNotFoundException("File has not been found!");
}
csvFile.useDelimiter("\n");
boolean first = true;
String productCode;
double price;
String description;
double weight;
int rating;
String category;
boolean ageRestriction;
String csvRows;
while (csvFile.hasNextLine()) {
csvRows = csvFile.nextLine();
if (first) {
first = false;
continue;
}
System.out.println(csvRows);
String[] fields = csvRows.split(",");
productCode = (fields[0].trim());
price = Double.parseDouble(fields[1].trim());
description = fields[2].trim();
weight = Double.parseDouble(fields[3].trim());
rating = Integer.parseInt(fields[4].trim());
category = fields[5].trim();
ageRestriction = Boolean.parseBoolean(fields[6].trim());
catalogue.addAProduct(new Item(productCode, price, description, weight, rating, category, ageRestriction));
}
csvFile.close();
}
}
ok so for a CSV file like this:
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"
here is a sample of how to read using Java Native Libraries
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CSVReader {
public static void main(String[] args) {
CSVReader obj = new CSVReader();
obj.run();
}
public void run() {
String csvFile = YOURFILEPATHHERE ;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("Country [code= " + country[4]
+ " , name=" + country[5] + "]");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
does this help?
If you are just doing a single look-up and then exiting then just remember the String you are looking for. As you parse the lines compare to see if you have a match and if you do then return that line.
For repeated searches that would be very inefficient though. Assuming your data set is not too large for memory you would be better off parsing the file and putting it into a Map:
Map<String, Data> dataMap = new HashMap<>();
Parse the file, putting all the lines into the map
Then the lookup just becomes:
Data d = dataMap.get(lineKey);
If d is null then there is no matching line. If it not null then you have found your line.
You can create an array list of object. An object for each line in the CSV. Then search the array object with your search criteria.
User CSVReader framework to read the csv file. Sample code (not exactly what you want)
FileInputStream fis = new FileInputStream(file);
CSVReader reader = new CSVReader(new BufferedReader( new InputStreamReader(fis, "UTF-8" )));
ArrayList<String> row = new ArrayList<String>();
ArrayList<Entry> entries = new ArrayList<Entry>();
// a line = ID, Name, Price, Description
while (!reader.isEOF()) {
reader.readFields(row);
if( row.size() >= 4)
entries.add(new Entry(row.get(0), row.get(1), row.get(2), row.get(3)));
}
System.out.println("Size : "+entries);

Reading from file and splitting the data in Java

I'm trying to read data from a .txt file. The format looks like this:
ABC, John, 123
DEF, Mark, 456
GHI, Mary, 789
I am trying to get rid of the commas and put the data into an array or structure (structure most likely).
This is the code I used to to extract each item:
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[]args){
try {
FileInputStream fstream = new FileInputStream("courses.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
At one point I had a print line in the "while" loop to see if the items would be split. They were. Now I'm just at a loss on what to do next. I'm trying to place each grouping into one structure. For example: ID - ABC. First Name - John. Room - 123.
I have a few books on Java at home and tried looking around the web. There is so much out there, and none of it seemed to lead me in the right direction.
Thanks.
Michael
create a class that looks something like this:
class structure {
public String data1;
public String data2;
public String data3;
}
This will form your basic data structure that you can use to hold the kind of data you have mentioned in your question. Now, you might want to follow proper object oriented methods like declaring all your fields as private, and writting getters and setters. you can find more on there here ... http://java.dzone.com/articles/getter-setter-use-or-not-use-0
Now, just outside your while loop, create an ArrayList like this: ArrayList<structure> list = new ArrayList<structure>(); This will be used to hold all the different rows of data that you will parse.
Now, in your while loop do something like this:
structure item = new structure();//create a new instance for each row in the text file.
item.data1 = splitOut[0];
item.data2 = splitOut[1];
item.data3 = splitOut[2];
list.add(item);
this will basically take the data that you parse in each row, put in the data structure that you declared by creating a new instance of it for each new row that is parsed. this finally followed by inserting that data item in the ArrayList using the list.add(item) in the code as shown above.
I would create a nice structure to store your information. I'm not sure if how you want to access the data, but here's a nice example. I'll go off of what you previously put. Please note that I only made the variables public because they're final. They cannot change once you make the Course. If you want the course mutable, create getters and setters and change the instance variables to private. After, you can use the list to retrieve any course you'd like.
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[] args) {
try {
FileInputStream fstream = new FileInputStream("courses.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
List<Course> courses = new LinkedList<Course>();
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
if (splitOut.length == 3) {
courses.add(new Course(splitOut[0], splitOut[1],
splitOut[2]));
} else {
System.out.println("Invalid class: " + strLine);
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
public static class Course {
public final String _id;
public final String _name;
public final String _room;
public Course(String id, String name, String room) {
_id = id;
_name = name;
_room = room;
}
}
}
public class File_ReaderWriter {
private static class Structure{
public String data;
}
public static void main(String[] args) throws IOException{
String allDataString;
FileInputStream fileReader = new FileInputStream ("read_data_file.txt");
DataInputStream in = new DataInputStream(fileReader);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(in));
String[] arrayString = {"ID - ", " NAME - ", " ROOM - "};
int recordNumber = 0;
Structure[] structure = new Structure[10];
for (int i = 0; i < 10; i++)
structure[i] = new Structure();
while((allDataString = bufferReader.readLine()) != null){
String[] splitOut = allDataString.split(", ");
structure[recordNumber].data = "";
for (int i = 0; i < arrayString.length; i++){
structure[recordNumber].data += arrayString[i] + splitOut[i];
}
recordNumber++;
}
bufferReader.close();
for (int i = 0; i < recordNumber; i++){
System.out.println(structure[i].data);
}
}
}
I modify your given code. It works. Try it and if any query then ask.

Categories

Resources