Results 1 to 15 of 15
Thread: Read txt file to arrayList
- 04-26-2010, 03:42 PM #1
Member
- Join Date
- Apr 2010
- Posts
- 20
- Rep Power
- 0
Read txt file to arrayList
Hallo,
I´m a newbie in Java and my boss want me to make a program to read the txt file through Java, since he want to use it later.
The example of txt file is like this:
************************************************** *******
* SIDAK *
************************************************** *******
* MISS RATIO: 4.15 *
* SHOOT RANGE: 36.2 [mm] *
************************************************** *******
* No.: Z [mm] Y [mm] F [mm/1000] *
************************************************** *******
Name: KIRA;
Try: 1 of 36;
Load: 3;
1: 36.200 172.200 9.2
2: 36.200 172.095 8.9
3: 36.200 171.990 8.1
Name: KIRA;
Try: 2 of 36;
Load: 3;
1: 35.166 172.200 81.7
2: 35.166 172.095 109.9
3: 35.166 171.990 130.9
Name: YAMATO;
Try: 1 of 36;
Load: 4;
1: 36.200 172.200 8.6
2: 36.200 172.095 8.3
3: 36.200 171.989 8.1
4: 36.200 171.884 7.9
Java Code:import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class ReadSortiere { public static void main(String[] args) { try { List <Data> a = new ArrayList<Data>(); Scanner sc2 = new Scanner(new File("test.TXT")); while(sc2.hasNextDouble()) { double y = sc2.nextDouble(); double z = sc2.nextDouble(); double f = sc2.nextDouble(); Data data = new Data(y,z,f); a.add(data); System.out.println(y + " " + z + " " + f); } sc2.close(); } catch(FileNotFoundException e) { System.out.println("Fehler: Quelldatei existiert nicht"); System.exit(1); } catch(Exception e) { System.out.println("Fehler: Ein unbekannter Fehler ist aufgetreten"); System.exit(1); } } } class Data { private double mZ; private double mY; private double mF; public Data(double z, double y, double f) { mZ = z; mY = y; mF = f; } public double getZ() { return mZ; } public double getY() { return mY; } public double getF() { return mF; } }
Do anybody have any idea, how can I just read the (Y,Z,F) file to the listarray without change the txt file?
And how is to read the (Y,Z,F) for another Name from txt data?
Should I use another class or another array?
Later when I have the (Y,Z,F) data for every Name, I want to make a split graph to compare the result of the them.
It´s like this:
!
------(Y,Z,F) from KIRA ------! ------ (Y,Z,F) from YAMATO --------
!
N.B.for the txt data (Little explanation of the real txt data):
The Load in a txt data is actually random (can be 1, can be 300), so that why I use listarray. Every txt data always consists of 2 Names (like on the example KIRA and YAMATO).
thank you for every help :)
- 04-26-2010, 04:22 PM #2
Moderator
- Join Date
- Apr 2009
- Posts
- 13,541
- Rep Power
- 27
First step is build some classes that represent that data.
Not knowing exactly what it is I can't really tell you what to put in them, but it looks like one that has the name, try and load values, along with an array of another class which has the YZF values.
Then read through the file...each "Name:" is the start of a new instance of that main class, and you just read stuff into it until the next "Name:" (or whatever criterai you want to use).
ETA: Oh yes, and each of these then gets added to an array that will eventually hold all the data from that file (give or take).
- 04-26-2010, 04:42 PM #3
Member
- Join Date
- Apr 2010
- Posts
- 20
- Rep Power
- 0
mm... ok I´ll try to build some classes that represent the data.
What important here by read of txt data is just Name. Load is actually an index, that tells how many (z,y,f) number we´ll be get. And Try is actually useless, since for every another Try means we got another Z.
So my thought right now: I want to make a read and write class.
The read class will read the data, and every new NAME, the data will be set in the write class.
After the NAME, I write it as ListArray (z,y,f) ....
but how can I eliminate Try, Load, and the number of every load out of the Array?
Is my thought going on the right track?
N.B. I just realized that I have reversed Y and Z by the code :(
- 04-26-2010, 05:07 PM #4
Moderator
- Join Date
- Apr 2009
- Posts
- 13,541
- Rep Power
- 27
Java works best when you think in terms of objects and "real world" classes.
Read and Write aren't really real world parts of your problem.
Whatever that data is, is.
So...presumably that data format is fixed?
That is, you have a standard number of header lines (8 in that bit you've posted), followed by your real data, which is broken down into chunks...the first three lines giving you some stuff (of which you;re only interested in Name apparently), followed by the YZF data, of which there are variable numbers of lines, depending on Load?
So:
1. Read in 8 lines and throw them away (I haven't used Scanner, so you'll have to figure that out).
That gets rid of your header.
2. The next line is your Name, so get that and figure out how to ge the actual name part.
3. Skip the next line, since you say you don't need it.
4. Read in the load line to get the number.
5. Use that number to decide how many data lines you need to read in and read them.
Then start again, until you have no more lines.
Now, 2 through 5 could be part of your class constructor, but that's up to you.
- 04-26-2010, 06:20 PM #5
Senior Member
- Join Date
- Mar 2010
- Posts
- 952
- Rep Power
- 12
I would try to model the data the way the report models it -- once you've got your file loaded, it's easier to change to another model if you want to. So that means (if I understand it correctly, and maybe I don't):
Java Code:A collection of Shooters for each Shooter String name a collection of Trys for each Try int load a collection of Shots for each Shot double Z double Y double F
Code this inside out. Make a simple Shot class with three instance variables: double z, double y, and double f. Just do a constructor with those three parameters, and you're done.
Next do a Try class. For its instance variables it will have an int load, and an ArrayList<Shot> shots. Set the load in the constructor or a setter method, and write an addShot() method.
Then you do a Shooter class. It will have a String name and an ArrayList<Try> tries. It will be similar in structure to the Try class -- set the name in the constructor or a setter method, and write an addTry() method.
Finally, you're ready to write your file reader program. You'll create an ArrayList<Shooter> variable and fill it up as you read the file.
I know this seems terribly complicated, but it really isn't, and this is one of those cases where it's quicker and easier to Just Do It than to think of a way to avoid doing it. Once you're done with reading the file and filling up all of your different object types, you'll find that composing your output is really pretty easy -- you have everything you need, and it's already nicely organized for you.
Good luck! Show us what you come up with.
-Gary-
- 04-26-2010, 08:22 PM #6
Moderator
- Join Date
- Apr 2009
- Posts
- 13,541
- Rep Power
- 27
What he said...up there ^.
:)
- 04-27-2010, 02:57 PM #7
Member
- Join Date
- Apr 2010
- Posts
- 20
- Rep Power
- 0
Hi,
first I want to thank you all for you answers.
So, I´ve made the classes, but I don´t know what do I need to write for getting the data that I want.
Here are some of my classes code:
Java Code:public class Shot { private double z; private double y; private double f; public Shot(double z, double y, double f){ this.z = z; this.y = y; this.f = f; } public double getZ() { return z; } public double getY() { return y; } public double getF() { return f; } }
Java Code:import java.util.ArrayList; import java.util.Scanner; public class Try { int load; ArrayList<Shot> shots = new ArrayList<Shot> (load); private Try(int load){ this.load = load; } private setLoad() { return load; } private void addShot(){ Shot shot = new Shot(getZ(), getY(), getF()); } }
Java Code:public class Read { public static void main(String[] args) throws Exception { File file = new File ("test.txt"); ArrayList<Shooter> shooters = (ArrayList<Shooter>) readFrom(file); } private static ArrayList<Shooter> readFrom(File file) throws Exception { ArrayList<Shooter> shooters = new ArrayList<Shooter>(); Scanner scanner = new Scanner(file); while (scanner.hasNext()) { shooters.add(scanner.next()); System.out.println(shooters); } scanner.close(); return shooters; } }
thank you very much
- 04-27-2010, 03:57 PM #8
Moderator
- Join Date
- Apr 2009
- Posts
- 13,541
- Rep Power
- 27
See my 5 steps.
They'll need a bit of modifying because I only had two classes, and was missing the equivalent of your Try class, but that should give you a good basis to start.
I wouldn't use a Scanner since that breaks on whitespace (OK, you could change that). I'd get each line (after throwing away the first 8, assuming they're not worth anything to you) and work with them. For that I'd use a BufferedReader, and then split() on the lines I'm interested in.
- 04-28-2010, 12:46 AM #9
Senior Member
- Join Date
- Mar 2010
- Posts
- 952
- Rep Power
- 12
This class looks fine to me. It should be just what you need.
This is fine, but lots of people like to do this instead:
Java Code:List<Shot> shots = new ArrayList<Shot>();
You've declared a setter but written a getter here. You want a private void setLoad() that sets your load variable. I think you'll also want a default constructor that doesn't initialize load.
First, you want this method public, but as it is it doesn't make sense, as there's no Shot to call getZ(), getY() and getF() on. Either just write a simple public void addShot(Shot shot) or you could do public void addShot(double z, double y, double f).
You still need your Shooter class, of course. I haven't discussed your Read class yet (but your main() method is void, so it won't return shooters), but I agree with Tolls that I'd use a BufferedReader to get a line at a time, then pass that line to another method based on its starting characters. Here's some pseudo-code for each line you read:
Java Code:if the trimmed line is blank, continue (next iteration of loop) if the line starts with * continue if line starts with Name: call parseName() // these next three lines might conceivably go in your parseName() // method, but I think it makes more sense to have parseName() // stick to just the parsing of the name if new name is same as current name, continue, else finalize and store current Try and Shooter initialize new Shooter if line starts with Try: call parseTry() // similar to above -- the first of these two lines should probably // go into a separate method because you need the same logic // above. the second line makes sense within parseTry() finalize and store current Try initialize new Try if line starts with Load: call parseLoad() // which can immediately store itself in the current Try // at this point, we should have handled every possible line start // except for Shot lines, so we can safely do this: call parseShot() // it's a good idea to have parseShot() print/log a message if it encounters // anything on the line that doesn't make sense
-Gary-
- 04-28-2010, 03:31 PM #10
Member
- Join Date
- Apr 2010
- Posts
- 20
- Rep Power
- 0
Hi again... firstly I want to thank both of you for helping me until these steps.
Also... after I see the pseudo-code from gcalvin, I tried to write that must be writen unto it.
Here is my update code:
Java Code:import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import sun.rmi.runtime.Log; public class Read { private static final String STAR = "*"; private static final String NAME = "Name: "; private static final String TRY = "Try: "; private static final String LOAD = "Load: "; private List<Shooter> shooters = new ArrayList<Shooter>(); private List<Try> tries = new ArrayList<Try> (); private List<Shot> shots = new ArrayList<Shot> (); public static String fileName = "text.txt"; public static void main(String[] args) throws Exception { readTextFile(fileName); } public static void readTextFile(String fileName) { BufferedReader reader = null; String text = null; try { reader = new BufferedReader(new FileReader(fileName)); reader.ready(); while( (text = reader.readLine()) != null ) { if (!text.trim().equals("")) reader.readLine(); if (!text.startsWith(STAR)) reader.readLine(); if (!text.startsWith(NAME)) { String name = reader.readLine(); String spasi = "[ ]+"; if (name == name) { continue; } else { reader.close(); shooters.add(name.split(spasi)); new Shooter(name); } } if (!text.startsWith(TRY)) { reader.readLine(); tries.add(Integer.parseInt(reader.readLine())); reader.close(); new Try(load); } if (!text.startsWith(LOAD)) { reader.readLine(); Shooter shooter = new Shooter(); shooter.addTry(Integer.parseInt(reader.readLine())); reader.close(); } else { reader.readLine(); shots.add(Double.parseDouble(reader.readLine())); reader.close(); Log shots; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
Java Code:import java.util.ArrayList; import java.util.List; public class Try { private int load; private List<Shot> shots = new ArrayList<Shot> (); private Try(int load){ this.load = load; } private void setLoad(int value){ load = value; } private int getLoad() { return load; } public void addShot(double z, double y, double f){ shots.add(z, y, f); } }
Java Code:import java.util.ArrayList; import java.util.List; public class Shooter { private String name; private List<Try> tries = new ArrayList<Try> (); public Shooter() { } public Shooter(String name){ this.name = name; } private void setName(String str){ name = str; } private String getName() { return name; } public void addTry(int load){ tries.add(load); } }
I know it isn´t all correct and I have difficulties, especially about parse-Method.
Can you give me more explanation (or example) about how to write the method about that?
thank you very much again in advanceLast edited by koddy; 04-28-2010 at 04:04 PM.
- 04-28-2010, 03:44 PM #11
Moderator
- Join Date
- Apr 2009
- Posts
- 13,541
- Rep Power
- 27
Just one thing, without going through the whole code.
Use startsWith() rather than equals(). None of your lines actuall equals() those static Strings, but they do start with them.
And you don't want the "!" for some of those checks, but you'll find that out quickly enough.
What I will suggest is test the parsing without creating any objects (just use System.out), just to make sure the parsing code is doing what you think it should be doing.
- 04-28-2010, 04:40 PM #12
Senior Member
- Join Date
- Mar 2010
- Posts
- 952
- Rep Power
- 12
Your Try class looks better now, and your Shooter class looks good too. You're going to need some getter methods eventually, but we'll cross that bridge when we come to it.
Let's take a look at your Read class now...
Java Code:import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import sun.rmi.runtime.Log; public class Read { private static final String STAR = "*"; private static final String NAME = "Name: "; private static final String TRY = "Try: "; private static final String LOAD = "Load: "; private List<Shooter> shooters = new ArrayList<Shooter>(); private List<Try> tries = new ArrayList<Try> (); private List<Shot> shots = new ArrayList<Shot> ();
Java Code:public static String fileName = "text.txt"; public static void main(String[] args) throws Exception { readTextFile(fileName); }
Java Code:public static void readTextFile(String fileName) { BufferedReader reader = null; String text = null; try { reader = new BufferedReader(new FileReader(fileName)); reader.ready();
Java Code:while( (text = reader.readLine()) != null ) { if (!text.trim().equals("")) reader.readLine(); if (!text.startsWith(STAR)) reader.readLine();
Java Code:if (!text.startsWith(NAME)) { String name = reader.readLine(); String spasi = "[ ]+"; if (name == name) { continue; } else { reader.close(); shooters.add(name.split(spasi)); new Shooter(name); } } if (!text.startsWith(TRY)) { reader.readLine(); tries.add(Integer.parseInt(reader.readLine())); reader.close(); new Try(load); } if (!text.startsWith(LOAD)) { reader.readLine(); Shooter shooter = new Shooter(); shooter.addTry(Integer.parseInt(reader.readLine())); reader.close(); } else { reader.readLine(); shots.add(Double.parseDouble(reader.readLine())); reader.close(); Log shots; } } }
Java Code:catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
Java Code:finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
Take some time and go through the Mark Dexter tutorials:
Eclipse and Java for Total Beginners
The whole thing is about three hours in bite-sized chunks, and they will probably save you more time than that even on this one project. The parts on JUnit testing will be especially helpful to you as you write your parsing code.
You've come quite far already, and I'm confident you can do this. Just be patient with yourself and know that the frustration you encounter is something we've all been through. Good luck, and keep us posted!
-Gary-
- 04-29-2010, 09:59 AM #13
Member
- Join Date
- Apr 2010
- Posts
- 20
- Rep Power
- 0
Hallo again,
thanks again for the explanation :) You're all a big help for me until now.
So i try to write a parseName-Method(), but I don´t think it´s right.
Java Code:private static void parseName(String aName) { Scanner scanner = new Scanner(aName); if ( scanner.hasNext() ){ String nameindex = scanner.next(); String name = scanner.next(); System.out.println(name); Shooter.setName(name); } scanner.close(); }
Java Code:private void parseTry(String aTry){ StringTokenizer tokenizer = new StringTokenizer(aTry," "); String s0, s1, s2; s0 = tokenizer.nextToken(); s1 = tokenizer.nextToken(); s2 = tokenizer.nextToken(); System.out.println(s0);
If not, can you plz help me making a parsing Method, since I´m now clueless.
thanks you very much again :)Last edited by koddy; 04-29-2010 at 02:50 PM.
- 04-29-2010, 05:07 PM #14
Senior Member
- Join Date
- Mar 2010
- Posts
- 952
- Rep Power
- 12
From the StringTokenizer API page:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
Java Code:private String parseName(String textLine) { String[] result = textLine.split("[:;]"); return result[1].trim(); }
Java Code:private Shot parseShot(String textLine) { String[] result = textLine.split("[:; ]"); double z = Double.parseDouble(result[2]); double y = Double.parseDouble(result[3]); double f = Double.parseDouble(result[4]); return new Shot(z, y, f); }
-Gary-
- 04-29-2010, 05:15 PM #15
Senior Member
- Join Date
- Mar 2010
- Posts
- 952
- Rep Power
- 12
Oh, and as we mentioned earlier, parseShot will be handling text lines that we are only about 99% certain have shot data on them, so you may want to wrap those parseDouble() calls in a try/catch block (looking for NumberFormatException). I would probably just return a null if I don't have good Shot data, which means that your method that calls parseShot() should check for a null return.
-Gary-
Similar Threads
-
Read file from directory, update contents of the each file
By svpriyan in forum New To JavaReplies: 2Last Post: 05-11-2009, 10:07 AM -
how to read openproj(Projity) file i.e. ,POD file(Project Management file)
By mahendra.athneria in forum New To JavaReplies: 0Last Post: 02-11-2009, 09:53 AM -
How to read and write to a file without taking out the comments in the file
By MAGNUM in forum New To JavaReplies: 5Last Post: 02-05-2009, 10:28 AM -
How can I call my database read method to display its ArrayList?
By matpj in forum New To JavaReplies: 3Last Post: 01-29-2009, 10:20 AM -
How to read a text file from a Java Archive File
By Java Tip in forum Java TipReplies: 0Last Post: 02-08-2008, 09:13 AM
Bookmarks