Results 1 to 15 of 15
  1. #1
    koddy is offline Member
    Join Date
    Apr 2010
    Posts
    20
    Rep Power
    0

    Default Read txt file to arrayList

    Hallo,
    Im 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
    Ive write a code like this:
    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;
    }
    }
    With these code, I can read all the data. But what I want is actually just the (Y,Z,F) data for every Try and for every Name, since after I read the data into arrays, I want to draw a graph with the data.

    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.

    Its 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 :)

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,846
    Rep Power
    19

    Default

    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).

  3. #3
    koddy is offline Member
    Join Date
    Apr 2010
    Posts
    20
    Rep Power
    0

    Default

    mm... ok Ill 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 well 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 :(

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,846
    Rep Power
    19

    Default

    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.

  5. #5
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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
    At first glance it looks like you don't want to deal with all of this, but it really is simpler to deal with it and build a complete model while you're reading the file, and then ignore what you want to ignore afterward. Besides, it's good practice with object oriented coding, and it really doesn't take long once you get started.

    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-

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,846
    Rep Power
    19

    Default

    What he said...up there ^.
    :)

  7. #7
    koddy is offline Member
    Join Date
    Apr 2010
    Posts
    20
    Rep Power
    0

    Default

    Hi,
    first I want to thank you all for you answers.
    So, Ive made the classes, but I dont 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;
        }
    }
    Can you help me further, what should I do as the next step?

    thank you very much

  8. #8
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,846
    Rep Power
    19

    Default

    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.

  9. #9
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Quote Originally Posted by koddy View Post
    Hi,
    first I want to thank you all for you answers.
    So, Ive made the classes, but I dont 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;
        }
    }
    This class looks fine to me. It should be just what you need.
    Quote Originally Posted by koddy View Post
    Java Code:
    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class Try {
        int load;
        ArrayList<Shot> shots = new ArrayList<Shot> (load);
    This is fine, but lots of people like to do this instead:
    Java Code:
        List<Shot> shots = new ArrayList<Shot>();
    The abstract List has the functionality you need, and doing the declaration this way keeps your code flexible to change the back-end implementation at a later date. Also, if you initialize your ArrayList here, then load is implicitly 0, so using it to pre-size your ArrayList is meaningless.
    Quote Originally Posted by koddy View Post
    Java Code:
        private Try(int load){
            this.load = load;
        }
    
        private setLoad() {
            return load;
        }
    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.
    Quote Originally Posted by koddy View Post
    Java Code:
        private void addShot(){
            Shot shot = new Shot(getZ(), getY(), getF());
        }
    }
    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).

    Quote Originally Posted by koddy View Post
    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;
        }
    }
    Can you help me further, what should I do as the next step?

    thank you very much
    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
    There you go. Very good start!

    -Gary-

  10. #10
    koddy is offline Member
    Join Date
    Apr 2010
    Posts
    20
    Rep Power
    0

    Default

    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();
            }
        }
        }
    }
    and here is my Try class
    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);   
        }
    }
    and Shooter class
    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);
        }
    }
    Its what I can write until now....
    I know it isnt 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 advance
    Last edited by koddy; 04-28-2010 at 04:04 PM.

  11. #11
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,846
    Rep Power
    19

    Default

    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.

  12. #12
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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> ();
    Not bad so far. I'm not sure you need tries and shots here, but we'll keep looking.
    Java Code:
        
        public static String fileName = "text.txt";
    
        public static void main(String[] args) throws Exception {     
            readTextFile(fileName);
        }
    I usually like to instantiate an object of my class type in main() and call its methods, rather than making methods static, but it's a minor style point.
    Java Code:
        public static void readTextFile(String fileName)
        {
        BufferedReader reader = null;
        String text = null;
    
        try
        {
            reader = new BufferedReader(new FileReader(fileName));
            reader.ready();
    The .ready() method doesn't set the file to a ready state, but rather checks to see whether there is data to be read. Therefore this call is useless. You're checking for null on your readLine() call, though, so you don't really need .ready().
    Java Code:
            
            while( (text = reader.readLine()) != null )
            {
                if (!text.trim().equals("")) reader.readLine();
                                    
                if (!text.startsWith(STAR)) reader.readLine();
    No, just say "continue" and let the top of the loop read the next line.
    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;
                } 
            }
        }
    Break this code up into methods. It makes it much more readable and testable. Don't try to use == for comparing Strings -- use .equals() instead.
    Java Code:
        
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    Be careful about this sort of thing -- catching Exceptions and just printing stack traces. I confess I do it all too often myself, but it's a dangerous habit. You're allowing your code to continue when it probably shouldn't. If you're going to catch the Exception, then make sure you either put everything in a good state to continue running, or do a System.exit();
    Java Code:
        finally
        {
            try
            {
                if (reader != null)
                {
                    reader.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        }
    }
    Like Tolls says, write methods to do the parsing and test them one by one. Each method will take a String parameter (the complete line of text -- don't bother trying to pre-parse anything out of it) and will return an appropriate value.

    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-

  13. #13
    koddy is offline Member
    Join Date
    Apr 2010
    Posts
    20
    Rep Power
    0

    Default

    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 dont think its 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();      
        }
    And I try to make the parseTry-Method with different method than parseName.
    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);
    Do you think one of the method I write above will be worked?
    If not, can you plz help me making a parsing Method, since Im now clueless.

    thanks you very much again :)
    Last edited by koddy; 04-29-2010 at 02:50 PM.

  14. #14
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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.
    Guess that answers that. What I would do for name is probably this:
    Java Code:
        private String parseName(String textLine) {
            String[] result = textLine.split("[:;]");
            return result[1].trim();
        }
    parseLoad() and parseTry() will be similar (although for parseTry() your regex should be [:; ]). parseShot has three values on one line, so you may as well just create and return your Shot object right there:

    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);
        }
    BTW, I don't know if I ever found out... are you using Eclipse? If so, you really should take a look at the tutorial I linked earlier.

    -Gary-

  15. #15
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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

  1. Replies: 2
    Last Post: 05-11-2009, 10:07 AM
  2. Replies: 0
    Last Post: 02-11-2009, 09:53 AM
  3. Replies: 5
    Last Post: 02-05-2009, 10:28 AM
  4. Replies: 3
    Last Post: 01-29-2009, 10:20 AM
  5. How to read a text file from a Java Archive File
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 02-08-2008, 09:13 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •