Parse a semicolon separated file in Java - java

I have a excel file and the contents are shown below.
First line is header, second line on wards is the data.
Cell A1 contains line below (Header)
**IsShooting; Velocity; Location_x; Location_y; Location_z; Onslaught_ONSAV ; ***Event***; EventParams...**
Cell A2 contains below
0;0;0;0;0;0;0;0;0;0;0.000;0.000;0;0.000;0.000;None;0;0;0.000;-1983.610;-
Cell A3 Contains below
;0.250;0.000;0.000;0.000;0.000;***BOT_KILLED***;CTF-Geothermal.GBxBot10;XWeapons.DamTypeFlakChunk
Cell A4 Contains below
4.110;161.900;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;0.000;4.320;0.000;0.260;0.000;0.000;***FLAG_PICKEDUP***;0;CTF-Geothermal.GBxBot10
I want to know if there are any open Source CSV Parsers, I can use so that, I can get the data from the excel.
The above excel file contains 400 lines of data. All I want from this is the COUNT of FLAG_PICKEDUP & BOT_KILLED.
Thanks!

This is the easiest way I can think of. Use a BufferedReader to read each line. For each line split it into a String array, then check each String to see if it equals the constants that define flag pickups or bot kills.
I think Apache makes csv parser, but I've never used it. For something this simple it might just be easier to code it yourself. This is what I came up with in about 5 mins.
NOTE: All due respect, stackoverflow generally asks that you attempt to solve the problem yourself first. Since you didn't post code, we can't help you debug and we don't know if you tried to solve the problem yourself. This was simple, so I helped but you may find it easier to get support if you post your (failed) solution first.
public static void main(String[] args) throws Exception
{
int botKilledCount = 0, flagPickedUpCount = 0;
String line, botLiteral = "***BOT_KILLED***", flagLiteral = "***FLAG_PICKEDUP***";
BufferedReader reader = new BufferedReader(new FileReader(new File("!!YOUR FILE HERE!!")));
while ((line = reader.readLine()) != null)
for (String s : line.split(";"))
if (s.equals(botLiteral))
botKilledCount++;
else if (s.equals(flagLiteral))
flagPickedUpCount++;
System.out.println("Bot Killed Count: " + botKilledCount + ", Flag Pickup Count: " + flagPickedUpCount);
}
This was the output:
Bot Killed Count: 1, Flag Pickup Count: 1

Related

Importing two CSV files into Java and then parsing them. The first one works the second doesnt

Im working on my code where I am importing two csv files and then parsing them
//Importing CSV File for betreuen
String filename = "betreuen_4.csv";
File file = new File(filename);
//Importing CSV File for lieferant
String filename1 = "lieferant.csv";
File file1 = new File(filename1);
I then proceed to parse them. For the first csv file everything works fine. The code is
try {
Scanner inputStream = new Scanner(file);
while(inputStream.hasNext()) {
String data = inputStream.next();
String[] values = data.split(",");
int PInummer = Integer.parseInt(values[1]);
String MNummer = values[0];
String KundenID = values[2];
//System.out.println(MNummer);
//create the caring object with the required paramaters
//Caring caring = new Caring(MNummer,PInummer,KundenID);
//betreuen.add(caring);
}
inputStream.close();
}catch(FileNotFoundException d) {
d.printStackTrace();
}
I then proceed to parse the other csv file the code is
// parsing csv file lieferant
try {
Scanner inputStream1 = new Scanner(file1);
while(inputStream1.hasNext()) {
String data1 = inputStream1.next();
String[] values1 = data1.split(",");
int LIDnummer = Integer.parseInt(values1[0]);
String citynames = values1[1];
System.out.println(LIDnummer);
String firmanames = values1[2];
//create the suppliers object with the required paramaters
//Suppliers suppliers = new
//Suppliers(LIDnummer,citynames,firmanames);
//lieferant.add(suppliers);
}
inputStream1.close();
}catch(FileNotFoundException d) {
d.printStackTrace();
}
the first error I get is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Verbindung.main(Verbindung.java:61)
So I look at my array which is firmaname at line 61 and I think, well it's impossible that its out of range since in my CSV file there are three columns and at index 2 (which I know is the third column in the CSV file) is my list of company names. I know the array is not empty because when i wrote
`System.out.println(firmanames)`
it would print out three of the first company names. So in order to see if there is something else causing the problem I commented line 61 out and I ran the code again. I get the following error
`Exception in thread "main" java.lang.NumberFormatException: For input
string: "Ridge"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Verbindung.main(Verbindung.java:58)`
I google these errors and you know it was saying im trying to parse something into an Integer which cannot be an integer, but the only thing that I am trying to parse into an Integer is the code
int LIDnummer = Integer.parseInt(values1[0]);
Which indeed is a column containing only Integers.
My second column is also indeed just a column of city names in the USA. The only thing with that column is that there are spaces in some town names like Middle brook but I don't think that would cause problems for a String type. Also in my company columns there are names like AT&T but i would think that the & symbol would also not cause problems for a string. I don't know where I am going wrong here.
I cant include the csv file but here is a pic of a part of it. The length of each column is a 1000.
A pic of the csv file
Scanner by default splits its input by whitespace (docs). Whitespace means spaces, tabs and newlines.
So your code will, I think, split the whole input file at every space and every newline, which is not what you want.
So, the first three elements your code will read are
5416499,Prairie
Ridge,NIKE
1765368,Edison,Cartier
I suggest using method readLine of BufferedReader then calling split on that.
The alternative is to explicitly tell Scanner how you want it to split the input
Scanner inputStream1 = new Scanner(file1).useDelimiter("\n");
but I think this is not the best use of Scanner when a simpler class (BufferedReader) will do.
First of all, I would highly suggest you try and use an existing CSV parser, for example this one.
But if you really want to use your own, you are going to need to do some simple debugging. I don't know how large your file is, but the symptoms you are describing lead me to believe that somewhere in the csv there may be a missing comma or an accidental escape character. You need to find out what line it is. So run this code and check its output before it crashes:
int line = 1;
try {
Scanner inputStream1 = new Scanner(file1);
while(inputStream1.hasNext()) {
String data1 = inputStream1.next();
String[] values1 = data1.split(",");
int LIDnummer = Integer.parseInt(values1[0]);
String citynames = values1[1];
System.out.println(LIDnummer);
String firmanames = values1[2];
line++;
}
} catch (ArrayIndexOutOfBoundsException e){
System.err.println("The issue in the csv is at line:" + line);
}
Once you find what line it is, the answer should be obvious. If not, post a picture of that line and we'll see...

Java: How to read huge records (>10k)

Looking for best practice to read a file line by line which has >10 records and storing it in ArrayList.
My program was able to read to 3.5k records and ignoring rest of the records.
URL cityurl = ClassLoader.getSystemResource(citypath);
citybr = new BufferedReader(new FileReader(cityurl.getFile()));
for (String city = citybr.readLine(); city != null; city = citybr.readLine()) {
citycountryairport.add(citybr.readLine());
}
Thanks in advance!!
BufferedReader is a good choice for reading large files because it buffers the file and thus avoids loading the whole file into memory, see BufferedReader Doc.
Each time you call
readLine();
The next line of the file is read, in your code change :
citycountryairport.add(citybr.readLine());
to :
citycountryairport.add(city);
otherwise the lines read by the line
city = citybr.readLine()
will not be added to your list because you never add the String city to your list.

Regex wiping file

I have written a method in Java to delete a caret at the end of each line of a file. The method is as follows:
//Creates a new file, and deletes the temp file
public void createFinalFile() throws FileNotFoundException, IOException{
// read file data into a String
String data1 = new Scanner(new File(fileDirectoryString + "tempFile.txt")).useDelimiter("\\Z").next();
// replace all ^ from end of line using (?m) - MULTILINE switch
data1 = data1.replaceAll("(?m)\\^$", "");
PrintWriter docketFile3 = new PrintWriter(new FileWriter(fileDirectoryString + "Forclosure-Docket-"+startingYear+startingMonth+startingDay+"-"+endingYear+endingMonth+endingDay+".txt", true));
docketFile3.write(data1);
}
The issue is that sometimes the temp file will have all the information, but after the method is run the newly created file is blank and I am not sure why. An example of the temp file is:
04/02/2014^BR-12-005193^09/12/2012^P1^SF^DEPOSIT AMOUNT PAID CUYAHOGA COUNTY SHERIFF^
04/02/2014^BR-12-005193^09/12/2012^P1^CS^COST PAYMENT $860.90 CUYAHOGA COUNTY SHERIFF^
While it should just delete the caret at the end of each line, it seems to be deleting every line.
Your regular expression is not what's doing this. Though the function overall reminds me more of this than anything else, it should work. The one thing though that could be going wrong is that you aren't closing your output file. Add docketFile3.close(); as a line after you write the data out.

Read the five score in a textfile then print them back with the new score added to the list - ANDROID

In my program when the player submits a score it gets added to a local text file called localHighScores. This is list of the top five score the player has achieved while on that specific device.
I wasn't sure how to write to a new line using FileOutputStream (if you know please share), so instead I've inputted a space in between each score. Therefore what I am trying to do is when the player clicks submit the program will open the file and read any current data is saved. It will save it to an String Array, each element being one of the five score in the text file and when it hits a 'space' in the fie it will add the score just read to the write array element
The code I currently have is as follows:
String space = " ";
String currentScoreSaved;
String[] score = new String[5];
int i = 0;
try
{
BufferedReader inputReader = new BufferedReader(new InputStreamReader(openFileInput("localHighScore.txt")));
String inputString;StringBuffer stringBuffer = new StringBuffer();
while ((inputString = inputReader.readLine()) != null && i < 6)
{
if((inputString = inputReader.readLine()) != space)
{
stringBuffer.append(inputString + "\n");
i++;
score[i] = stringBuffer.toString();
}
}
currentScoreSaved = stringBuffer.toString();
FileOutputStream fos = openFileOutput("localHighScore.txt", Context.MODE_PRIVATE);
while (i < 6)
{
i++;
fos.write(score[i].getBytes());
fos.write(space.getBytes());
}
fos.write(localHighScore.getBytes());
//fos.newLine(); //I thought this was how you did a new line but sadly I was mistaken
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
Now you will notice this doesn't re arrange the score if a new highscore is achieved. That I am planning on doing next. For the moment I am just trying to get the program to do the main thing which is read in the current data, stick it in an Array then print it back to that file along with the new score
Any Ideas how this might work, as currently it's printing out nothing even when I had score in the textfile before hand
I'm only a first year student in Java programming and I am a new user here at stackoverflow.com, so pardon me if coding for android has some special rules I don't know about, which prevents this simple and humble example from working. But here is how I would read from a file in the simplest of ways.
File tempFile = new File("<SubdirectoryIfAny/name_of_file.txt");
Scanner readFile = new Scanner( tempFile );
// Assuming that you can structure the file as you please with fx each bit of info
// on a new line.
int counter = 0;
while ( readFile.hasNextLine() ) {
score[counter] = readFile.nextLine();
counter++;
}
As for the writing back to the file? Put it in an entirely different method and simply make a simplified toString-like method, that prints out all the values the exact way you want them in the file, then create a "loadToFile" like method and use the to string method to print back into the file with a printstream, something like below.
File tempFile = new File("<SubdirectoryIfAny/name_of_file.txt");
PrintStream write = new PrintStream(tempFile);
// specify code for your particular program so that the toString method gets the
// info from the string array or something like that.
write.print( <objectName/this>.toStringLikeMethod() );
// remember the /n /n in the toStringLikeMethod so it prints properly in the file.
Again if this is something you already know, which is just not possible in this context please ignore me, but if not I hope it was useful. As for the exceptions, you can figure that you yourself. ;)
Since you are a beginner, and I assume you are trying to get things off the ground as quickly as possible, I'd recommend using SharedPreferences. Basically it is just a huge persistent map for you to use! Having said that... you should really learn about all the ways of storage in Android, so check out this document:
http://developer.android.com/guide/topics/data/data-storage.html
The Android docs are awesome! FYI SharedPreferences may not be the best and awesomest way to do this... but I'm all for quick prototyping as a learner. If you want, write a wrapper class around SharedPreferences.

Java - Load file, replace string, save

I have a program that loads lines from a user file, then selects the last part of the String (which would be an int)
Here's the style it's saved in:
nameOfValue = 0
nameOfValue2 = 0
and so on. I have selected the value for sure - I debugged it by printing. I just can't seem to save it back in.
if(nameOfValue.equals(type)) {
System.out.println(nameOfValue+" equals "+type);
value.replace(value, Integer.toString(Integer.parseInt(value)+1));
}
How would I resave it? I've tried bufferedwriter but it just erases everything in the file.
My suggestion is, save all the contents of the original file (either in memory or in a temporary file; I'll do it in memory) and then write it again, including the modifications. I believe this would work:
public static void replaceSelected(File file, String type) throws IOException {
// we need to store all the lines
List<String> lines = new ArrayList<String>();
// first, read the file and store the changes
BufferedReader in = new BufferedReader(new FileReader(file));
String line = in.readLine();
while (line != null) {
if (line.startsWith(type)) {
String sValue = line.substring(line.indexOf('=')+1).trim();
int nValue = Integer.parseInt(sValue);
line = type + " = " + (nValue+1);
}
lines.add(line);
line = in.readLine();
}
in.close();
// now, write the file again with the changes
PrintWriter out = new PrintWriter(file);
for (String l : lines)
out.println(l);
out.close();
}
And you'd call the method like this, providing the File you want to modify and the name of the value you want to select:
replaceSelected(new File("test.txt"), "nameOfValue2");
I think most convenient way is:
Read text file line by line using BufferedReader
For each line find the int part using regular expression and replace
it with your new value.
Create a new file with the newly created text lines.
Delete source file and rename your new created file.
Please let me know if you need the Java program implemented above algorithm.
Hard to answer without the complete code...
Is value a string ? If so the replace will create a new string but you are not saving this string anywhere. Remember Strings in Java are immutable.
You say you use a BufferedWriter, did you flush and close it ? This is often a cause of values mysteriously disappearing when they should be there. This exactly why Java has a finally keyword.
Also difficult to answer without more details on your problem, what exactly are you trying to acheive ? There may be simpler ways to do this that are already there.

Categories