Split multi line delimiter - java

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);
}
}

Related

How can read a txt file so that all words are placed in a new array element and not every new line is placed in a element?

I currently have written a code that is able to read through a .txt file and for every new line it will be placed in a array element (not very hard). It works but this was not my initial intention, I want to have every word placed in a new array element, not after every new line. Here is my current code, can someone maybe help? Thank you!
public static ArrayList<String> read_file() {
try {
ArrayList<String> data_base = new ArrayList<String>();
Scanner s1 = new Scanner(new File("C:\\Users\\Jcool\\OneDrive\\A Levels\\Computer Science\\CSV files\\data convert\\convert.txt"));
while(s1.hasNextLine()) {
data_base.add(s1.nextLine());
}
return data_base;
}catch(FileNotFoundException e) {
}
return null;
}
Read all the lines at once and split them into array.
private static String readAllBytes(String filePath)
{
String content = "";
try
{
content = new String ( Files.readAllBytes( Paths.get(filePath) ) );
}
catch (IOException e)
{
e.printStackTrace();
}
return content;
}
Create a method named readAllBytes and call it like this;
/* String to split. */
String stringToSplit = readAllBytes(filePath);
String[] tempArray;
/* delimiter */
String delimiter = " ";//space if its a file contains words
/* given string will be split by the argument delimiter provided. */
tempArray = stringToSplit.split(delimiter);
If you mean to split your lines into array check this answer.
Take a look at the split(String) method. It returns a String[]. As an example
String string = "AAA-BBB";
String[] parts = string.split("-");
String part1 = parts[0]; // AAA
String part2 = parts[1]; // BBB

Read File into ArrayList from .txt file on begging of program

So i got a Java Class of Konto, which got:
private String navn;
private int medlemdsnummer;
private String årstal;
private String måned;
private String dag;
LocalDate localDate;
They are used like this:
ArrayList<Konto> kontoArrayList = new ArrayList<>();
And I save my ArrayList to a .txt document before the program shutdowns:
private static void saveToFile(ArrayList<Konto> kontoArrayList) throws IOException {
String content = new String(Files.readAllBytes(Paths.get("medlemmer.txt")));
PrintStream printStream = new PrintStream("medlemmer.txt");
for (int i = 0; i < kontoArrayList.size(); i++) {
printStream.println(content + kontoArrayList.get(i).getMedlemdsnummer() + ": " + kontoArrayList.get(i).getNavn() + " " +
kontoArrayList.get(i).getLocalDate());
}
}
They end up looking like this in the .txt file:
1: Kasper 1996-11-20
2: Jonas 1996-04-27
3: Jesper 1996-05-14
Okay, so far so good. Now for the question: When the program is turned on, I want to make it able to load the .txt file from the beginning and "transfer" it to an ArrayList of Konto. So that i later can use my method (addNewMember). I saw a lot of example on the internet, but they all use:
ArrayList<String> somename = new ArrayList<String>();
I want to use:
ArrayList<Konto> konto = new ArrayList<Konto>();
Is this possible, if so how do to?
If not what could i do instead?
Thanks in advance, Victor.
You can read all lines from the file as string and split this strings by spaces.
And then create new objects with parsing of options.
Something like this:
List<String> strings = Files.readAllLines(Paths.get("test.txt"));
List<Konto> kontos = new ArrayList<>();
for (String string : strings) {
String[] data = string.split(" ");
kontos.add(new Konto(data[1], new Date(data[2])));
}
Or using Streams:
List<Konto> kontos = Files.lines(Paths.get("test.txt")) // String
.map(line -> line.split(" ")) // String[]
.map(data -> new Konto(data[1], new Date(data[2])) // Konto
.collect(Collectors.toList());
Something like the following, you've got to check it
class TestParse {
public TestParse(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, ",");
if(tokenizer.countTokens() != 3) {
throw new RuntimeException("error");
}
s1 = tokenizer.nextToken();
s2 = tokenizer.nextToken();
s3 = tokenizer.nextToken();
}
private String s1;
private String s2;
private String s3;
}
public class TestRead {
public static void main(String[] args) throws Exception {
List<TestParse> testParses = new ArrayList<TestParse>();
BufferedReader in = new BufferedReader(new FileReader("file.txt"));
String line;
while((line = in.readLine()) != null) {
testParses.add(new TestParse(line));
}
in.close();
}
}
I think one way you can try is read line by line, and define a Konto constructor that accept a string.
Edit: You can follow the below answer from Lucem. But I think I will do it a little different
List<String> strings = Files.readAllLines(Paths.get("fileName.txt"));
List<Konto> kontos = new ArrayList<>();
for (String s: strings) {
kontos.add (new Konto(s))
}
or using Streams:
List<Konto> kontos = Files.lines(Paths.get("fileName.txt"))
.map(line -> new Konto(line));
.collect(Collectors.toList());
And then in Konto class add a constructor that accept a string and manipulate it. Because you didn't add the class Konto here, I didn't know the exact name of your properties, so I let it be "yourPropertyNumber", "yourPropertyString" and "yourPropertyDate"
class Konto {
public Konto (String input) {
// Split based on white space
String[] dataParts = input.split(" ");
// Get rid of the semicolon
String number = dataParts[0].substring(0, dataParts[0].length - 1);
yourPropertyNumber = parseInt(number);
yourPropertyString = dataParts[1];
yourPropertyDate = new Date(dataParts[2]);
}
// Your other code here
}
The reason I want to pass a String to a constructor rather than parse the string where I read the file is that I think it is easier to debug or make change in the way it reads the string.
Hope this help.

Reading a text file into multiple arrays in Java

I'm currently working on a program that reads in a preset text file and then manipulates the data in various ways. I've got the data manipulation to work with some dummy data but I still need to get the text file read in correctly.
The test file looks like this for 120 lines:
Aberdeen,Scotland,57,9,N,2,9,W,5:00,p.m. Adelaide,Australia,34,55,S,138,36,E,2:30,a.m. Algiers,Algeria,36,50,N,3,0,E,6:00,p.m.(etc etc)
So each of these needs to be read into its own array, in order String[] CityName,String[] Country,int[] LatDeg,int[] LatMin,String[] NorthSouth,int[] LongDeg,int LongMin,String[] EastWest,int[] Time.String[] AMPM
So the problem is that while I'm reasonably comfortable with buffered readers, designing this particular function has proven difficult. In fact, I've been drawing a blank for the past few hours. It seems like it would need multiple loops and counters but I can't figure out the precisely how.
I am assuming that you have one city per line type of file structure. If it is not, it will require a bit of tweaking in the following solution:
I will do the following way if I am more comfortable with BufferReader as you say:
List<List<String>> addresses = new ArrayList<List<String>>();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
for(String line; (line = br.readLine()) != null; ) {
addresses.add(line.split(","));
}
}
Later, let's say you want to retrieve the country information of say 'Adelaid', you can try the following:
for (List<String> cityInfo : addresses) {
if("Adelaid".equals(cityInfo.get(0)) {
country = cityInfo.get(1);
}
}
Instead of creating different arrays (like String[] CityName,String[] Country, etc.,), try using a Domain Object.
Here, you can have a Domain object or Custom class Location with attributes
public class Location
{
private String cityName;
private String country;
private String latDeg;
etc
getters();
setters();
}`
Then you can write a file reader, each line item in the file will be a Location. So result will have
Location[] locations;
or
List locations;`
To carry out this task I should think the first thing you want to do is establish how many lines of data actually exist within the data file. You say it is 120 lines but what if it happens that it will be more or less? We would want to know exactly what it is so as to properly initialize all our different Arrays. We can use a simple method to accomplish this, let's call it the getFileLinesCount() method which will ulitmately return a Integer value that would be the number of text lines the data file holds:
private int getFileLinesCount(final String filePath) {
int lines = 0;
try{
File file =new File(filePath);
if(file.exists()){
FileReader fr = new FileReader(file);
try (LineNumberReader lnr = new LineNumberReader(fr)) {
while (lnr.readLine() != null){ lines++; }
}
}
else {
throw new IllegalArgumentException("GetFileLinesCount() Method Error!\n"
+ "The supplied file path does not exist!\n(" + filePath + ")");
}
}
catch(IOException e){ e.printStackTrace(); }
return lines;
}
Place this method somewhere within your main class. Now you need to Declare and initialize all your Arrays:
String filePath = "C:\\My Files\\MyDataFile.txt";
int lines = getFileLinesCount(filePath);
String[] CityName = new String[lines];
String[] Country = new String[lines];
int[] LatDeg = new int[lines];
int[] LatMin = new int[lines];
String[] NorthSouth = new String[lines];
int[] LongDeg = new int[lines];
int[] LongMin = new int[lines];
String[] EastWest = new String[lines];
int[] Time = new int[lines];
String[] AMPM = new String[lines];
Now to fill up all those Arrays:
public static void main(String args[]) {
loadUpArrays();
// Do whatever you want to do
// with all those Arrays.....
}
private void loadUpArrays() {
// Read in the data file.
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String sCurrentLine;
int x = 0;
// Read in one line at a time and Fill the Arrays...
while ((sCurrentLine = br.readLine()) != null) {
// Split each line read into an array upon itself.
String[] fileLine = sCurrentLine.split(",");
// Fill our required Arrays...
CityName[x] = fileLine[0];
Country[x] = fileLine[1];
LatDeg[x] = Integer.parseInt(fileLine[2]);
LatMin[x] = Integer.parseInt(fileLine[3]);
NorthSouth[x] = fileLine[4];
LongDeg[x] = Integer.parseInt(fileLine[5]);
LongMin[x] = Integer.parseInt(fileLine[6]);
EastWest[x] = fileLine[7];
Time[x] = Integer.parseInt(fileLine[8]);
AMPM[x] = fileLine[9];
x++;
}
br.close();
}
catch (IOException ex) { ex.printStackTrace(); }
}
Now, I haven't tested this, I just quickly punched it out but I think you can get the jest of it.
EDIT:
As #Mad Physicist has so graciously pointed out within his comment below, a List can be used to eliminate the need to count file lines therefore eliminating the need to read the data file twice. All the file lines can be placed into the List and the number of valid file lines can be determined by the size of the List. Filling of your desired arrays can now also be achieved by iterating through the List elements and processing the data accordingly. Everything can be achieved with a single method we'll call fillArrays(). Your Arrays declaration will be a little different however:
String[] CityName;
String[] Country;
int[] LatDeg;
int[] LatMin;
String[] NorthSouth;
int[] LongDeg;
int[] LongMin;
String[] EastWest;
String[] Time;
String[] AMPM;
public static void main(String args[]) {
fillArrays("C:\\My Files\\MyDataFile.txt");
// Whatever you want to do with all
// those Arrays...
}
private void fillArrays(final String filePath) {
List<String> fileLinesList = new ArrayList<>();
try{
File file = new File(filePath);
if(file.exists()){
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String strg;
while((strg = br.readLine()) != null){
// Make sure there is no blank line. If not
// then add line to List.
if (!strg.equals("")) { fileLinesList.add(strg); }
}
br.close();
}
}
else {
throw new IllegalArgumentException("GetFileLinesCount() Method Error!\n"
+ "The supplied file path does not exist!\n(" + filePath + ")");
}
// Initialize all the Arrays...
int lines = fileLinesList.size();
CityName = new String[lines];
Country = new String[lines];
LatDeg = new int[lines];
LatMin = new int[lines];
NorthSouth = new String[lines];
LongDeg = new int[lines];
LongMin = new int[lines];
EastWest = new String[lines];
Time = new String[lines];
AMPM = new String[lines];
// Fill all the Arrays...
for (int i = 0; i < fileLinesList.size(); i++) {
String[] lineArray = fileLinesList.get(i).split(",");
CityName[i] = lineArray[0];
Country[i] = lineArray[1];
LatDeg[i] = Integer.parseInt(lineArray[2]);
LatMin[i] = Integer.parseInt(lineArray[3]);
NorthSouth[i] = lineArray[4];
LongDeg[i] = Integer.parseInt(lineArray[5]);
LongMin[i] = Integer.parseInt(lineArray[6]);
EastWest[i] = lineArray[7];
Time[i] = lineArray[8];
AMPM[i] = lineArray[9];
}
}
catch(IOException e){ e.printStackTrace(); }
}
On another note...your Time Array can not be Integer since in data, what is considered the time contains a colon (:) which is a alpha character therefore (in case you haven't noticed) I have changed its declaration to String[]

Reading and Saving .txt files into an array in 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

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