Solved

Newbie needs help with some issues (reader from text file and setting file path)...

Posted on 2004-07-31
4
221 Views
Last Modified: 2010-03-31
Ok, first off, I am a Java application newbie, so these might be simple issues, but they aren't to me.

Project Background:  I am trying to make a Java application that will be used to create RPG characters.  There are many different mods(different rules that can be used to make characters) so I plan on using txt files for the different mods that can be used.  Inside those txt files I plan on using tabs and returns(I guess this is the best way) to read information from the files, and so that people can make their own mod files.  I will use a master txt file that lists all the mod txt files.  I want this application to be an exe file.

First problem:  What's the easiest way to make the class file executable by anyone?

Second problem:  The first thing I need to be able to do, is have the user set the path to where their mod files are stored.  Basicly I need like a "Set path:" textbox, but would like the option for them to click a button and have them beable to navigate their computer drives.  Is there already a class for this that I can just call?

Third problem:  Say I have a txt file that looks like this:

Name:     Bob
Age:       21

The space between "name:" and "bob" is a tab, and the same on the next line.  If I am using DataInputStream to read the file, how to I populate a combobox1 with bob, and a combobox2 with 21.  In other words what command is used to read something, then skip the tab and read the next bit of info, then skip to the next line and read that info.

If I am headed the wrong way with any of this, or if anyone has a better idea how to do any of this, I am a newbie and know it, so please chime in.  Thanks.
0
Comment
Question by:lokimarine
4 Comments
 
LVL 1

Accepted Solution

by:
lowenbrausat earned 250 total points
Comment Utility
Hi lokimarine, it seems that u have a big problem in hands. Lets break it in smaller ones to make easier the solution.
First, you need a way to save some data to disk.
I belong to a relational data base enviroment so my best advise for you is to use some kind of data structure similar to tables. You could use CSV (Comma Separated Value) files to hold data. However, I'll show you a different solution, similar to a java properties file that I've already implemented in one of my applicactions. It is very easy to use and I believe this will help you get working what you need.

The next class, named PropertyFile works this way (PropertyFile implementation below).

1) create a file named GeneralPaths.txt to hold the other rules files path.

GeneralPaths.txt content:
*************************
; any line begining with ';' or '#' is a comment
; RULEPATHS is a Header

[RULEPATHS]
; rulefile1 is a key and the text after '=' is the value for the key
; always use absolute paths to the files (include extension of file)
rulefile1=c:\MyRules\rulefile1.txt
rulefile2=c:\MyRules\rulefile2.txt
;...
*************************

rulefile1.txt content:
*************************
[RULE1HEADER]
rulename=RULE NUMBER ONE
rulespec=the rule spec
;...

[RULE1HEADER2]
rulename=RULE NUMBER TWO
rulespec=the rule spec ;...

[RULE1HEADER3]
rulename=RULE NUMBER nn
rulespec=the rule spec ;...
;as you can see, you may have several HEADERS in the same file.
*************************

The class implementation: (I'll show you how to open/modify/save a file after class implementation...)

import java.io.*;
import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;

public class PropertyFile
{

  Hashtable sections;
  String    propertyFileName; //used to store the Absolute path or URL (as String) when properties are read from a file.

  /**
   * Constructor for the IniFile object
   */
  public PropertyFile()
  {
    sections = new Hashtable();
  }

  /**
   * Constructor for the IniFile object
   *
   * @param filename                   Description of Parameter
   * @exception FileNotFoundException  Description of Exception
   */
  public PropertyFile(String filename) throws FileNotFoundException
  {
    this();
    load(filename);
  }

  /**
   * Constructor for the IniFile object
   *
   * @param url              Description of Parameter
   * @exception IOException  Description of Exception
   */
  public PropertyFile(URL url) throws IOException
  {
    this();
    propertyFileName = url.toString();
    load(url.openStream());
  }

  /**
   * Constructor for the IniFile object
   *
   * @param input            Description of Parameter
   * @exception IOException  Description of Exception
   */
  public PropertyFile(InputStream input) throws IOException
  {
    this();
    load(input);
  }
///////////////////////////////////////////////////////////////////////

  /**
   * Returs the Name (Absolut path or URL) of the property file loaded
   * by this object.
   * @return String Property file name.
   */
  public String getPropertyFileName(){  return this.propertyFileName;}



  /**
   * Gets the Sections attribute of the IniFile object
   * @return   The Sections value
   */
  public Hashtable getSections()
  {
    return sections;
  }



  /**
   * Returns all the section names from the property file.
   * @return String[].
   */
  public String[] getSectionsNames()
  {
    try{
          int i=0;
          String[] sectionNames = new String[sections.size()];
          for (Enumeration f = sections.keys(); f.hasMoreElements(); i++)
          {
            sectionNames[i] = (String) f.nextElement();
          }
          return sectionNames;
       }catch(Exception ex)
        {
          System.out.println("No Sections on the propety file. Returning null.");
          return null;
        }
  }



  /**
   * Returns a Hashtable that has all the pairs Key=KeyValue
   * of the given section.
   * @param section  The section that has the pairs.
   * @return         Hashtable.
   */
  public Hashtable getSection(String section)
  {
    return (Hashtable) (sections.get(section.toLowerCase()));
  }

  /**
   * Gets the NullOrEmpty attribute of the IniFile object
   *
   * @param section  Description of Parameter
   * @param key      Description of Parameter
   * @return         The NullOrEmpty value
   */
  public boolean isNullOrEmpty(String section, String key)
  {
    String value = getKeyValue(section, key);
    return (value == null || value.length() == 0);
  }

  /**
   * Gets the KeyValue attribute of the IniFile object
   *
   * @param section  Description of Parameter
   * @param key      Description of Parameter
   * @return         The KeyValue value
   */
  public String getKeyValue(String section, String key)
  {
    try {
          return (String) getSection(section).get(key.toLowerCase());
        } catch (NullPointerException e)
          {
            System.err.println("Clave "+key+" no encontrada en sección "+section);
            return null;
          }
  }

  /**
   * Gets the KeyIntValue attribute of the IniFile object
   *
   * @param section  Description of Parameter
   * @param key      Description of Parameter
   * @return         The KeyIntValue value
   */
  public int getKeyIntValue(String section, String key)
  {
    return getKeyIntValue(section, key, 0);
  }

  /**
   * Gets the KeyIntValue attribute of the IniFile object
   *
   * @param section       Description of Parameter
   * @param key           Description of Parameter
   * @param defaultValue  Description of Parameter
   * @return              The KeyIntValue value
   */
  public int getKeyIntValue(String section, String key, int defaultValue)
  {
    String value = getKeyValue(section, key.toLowerCase());
    if (value == null) {
      return defaultValue;
    }
    else {
      try {
        return Integer.parseInt(value);
      } catch (NumberFormatException e) {
        return 0;
      }
    }
  }

  /**
   * Gets the KeysAndValues attribute of the IniFile object
   *
   * @param aSection  Description of Parameter
   * @return          The KeysAndValues value
   */
  public String[][] getKeysAndValues(String aSection)
  {
    Hashtable section = getSection(aSection);
    if (section == null)
    {
      return null;
    }
    String[][] results = new String[section.size()][2];
    int i = 0;
    for (Enumeration f = section.keys(), g = section.elements(); f.hasMoreElements(); i++)
    {
      results[i][0] = (String) f.nextElement();
      results[i][1] = (String) g.nextElement();
    }
    return results;
  }




  /**
   *
   * @param query
   * @return String
   */
  public String getSectionWhere(String[][] query)
  {
    String result = null;

    for (Enumeration e = sections.keys(); e.hasMoreElements(); )
    {
      String current = (String)e.nextElement();
      boolean match = true;
      for (int i = 0, c = query.length; i < c; i++)
      {
        if (getKeyValue(current, query[i][0]) == null || getKeyValue(current, query[i][0]).equals(query[i][1]) == false)
        {
          match = false;
          break;
        }
      }
      if (match)
      {
        result = current;
        break;
      }
    }
    return result;
  }





////Load Area////////////////////////////////////////////////////////////////////////////

  /**
   * Description of the Method
   *
   * @param filename                   Description of Parameter
   * @exception FileNotFoundException  Description of Exception
   */
  public void load(String filename) throws FileNotFoundException
  {
    load(new FileInputStream(filename));
    propertyFileName = filename;
  }


  /**
   * Description of the Method
   *
   * @param in  Description of Parameter
   */
  public void load(InputStream in)
  {
    try {
            BufferedReader input = new BufferedReader(new InputStreamReader(in));
            String read;
            Hashtable section = null;
            String section_name;
            while ((read = input.readLine()) != null)
            {
              if (read.startsWith(";") || read.startsWith("#"))
              {
                continue;
              }
              else
                if (read.startsWith("["))
                {
                    // new section
                    section_name = read.substring(1, read.indexOf("]")).toLowerCase();
                    section = (Hashtable) sections.get(section_name);
                    if (section == null)
                    {
                      section = new Hashtable();
                      sections.put(section_name, section);
                    }
                }
                else
                  if (read.indexOf("=") != -1 && section != null)
                  {
                    // new key
                    String key = read.substring(0, read.indexOf("=")).trim().toLowerCase();
                    String value = read.substring(read.indexOf("=") + 1).trim();
                    section.put(key, value);
                  }
            }
          if(input != null){input.close();}//Try to close the opened file...
      } catch (Exception e) {  e.printStackTrace();  }
  }





////Save Area////////////////////////////////////////////////////////////////////////////
  /**
   * Saves modifications to the opened property file.
   * If properties were loaded from an InputStream (diferent from a file), then this method won't do anything
   * but print an Error to the system console.
   */
  public void save()
  {
    //if propertyFileName is invalid, no further action done. Notify Error.
    if(propertyFileName == null || propertyFileName.length() == 0){ System.err.println("No se ha definido un nombre de archivo donde grabar las propiedades.\n"); return; }
    String filePath = propertyFileName;
    try{
         URL fileURL = new URL(propertyFileName);
         filePath = fileURL.getFile().substring(1);
       }catch(MalformedURLException mURLe){}

    try{
          save(filePath);
       }catch(IOException ioe)
        {
          System.err.println("Error al intentar grabar el archivo de propiedades: "+propertyFileName);
          System.err.println("ioe Error = "+ioe.getMessage());
        }
  }





  /**
   * Saves all de sections, keys and keyValues to the given filename
   * using a FileOutputStream to get the job done.
   *
   * @param filename         the system-dependent filename
   * @exception IOException  If the file exists but is a directory rather than a regular file,
   *                         does not exist but cannot be created, or cannot be opened for any
   *                         other reason then a FileNotFoundException is thrown.
   */
  public void save(String filename) throws IOException
  {
    save(new FileOutputStream(filename));
  }




  /**
   * Description of the Method
   *
   * @param out  OutputStream
   */
  public void save(OutputStream out)
  {
    try {
          PrintWriter output = new PrintWriter(out);
          String section;
          for (Enumeration e = sections.keys(); e.hasMoreElements(); )
          {
            section = (String) e.nextElement();
            output.println("[" + section + "]");
            for (Enumeration f = getSection(section).keys(), g = getSection(section).elements();  f.hasMoreElements(); )
            {
              output.println(f.nextElement() + "=" + g.nextElement());
            }
          }
          output.flush();
          output.close();
          out.flush();
          out.close();
        } catch (Exception e) {  e.printStackTrace();  }
  }





/////Adding Area/////////////////////////////////////////////////////////////////////////

  /**
   * Sets the KeyValue attribute of the IniFile object
   *
   * @param section  The new KeyValue value
   * @param key      The new KeyValue value
   * @param value    The new KeyValue value
   */
  public void setKeyValue(String section, String key, String value)
  {
    try {
          getSection(section).put(key.toLowerCase(), value);
        } catch (NullPointerException e)
          {
            System.err.println("Error when try to setKeyValue "+value+" on key "+key+" on Section "+section);
          }
  }



  /**
   * Adds a feature to the Section attribute of the IniFile object
   *
   * @param section  The feature to be added to the Section attribute
   */
  public void addSection(String section)
  {
    sections.put(section.toLowerCase(), new Hashtable());
  }

  /**
   * Description of the Method
   *
   * @param section  Description of Parameter
   */
  public void removeSection(String section)
  {
  }


  /**
   * Adds a new section to the property file with a new Key and it's value.
   * @param section     new section to be added
   * @param key         new key to be added to the new section
   * @param keyValue    the keyValue for the new key
   */
  public void addKeyToSection(String section, String key, String keyValue)
  {
    Hashtable s = getSection(section);
    if(s != null)
    {//if the section already exists, only add the key and value.
      s.put(key, keyValue);
    }
    else
      { //if the section doesn't exists, then create a new Hashtable for the new key and value, then add it to sections.
        Hashtable hashSection = new Hashtable(1);
        hashSection.put(key, keyValue);
        this.sections.put(section, hashSection);
      }
  }



  public void addKeyToSection(String section, String key, String[] keyValues)
  {
    String keyValue;
    for(int i=0; i < keyValues.length; i++)
    {

    }
  }





////Testing Area/////////////////////////////////////////////////////////////////////////
  /**
   * Simple test function
   *
   * @param args           The command line arguments
   * @exception Exception  Description of Exception
   */
  public static void main(String[] args) throws Exception
  {
    (new PropertyFile()).load(new FileInputStream(args[0]));
  }
}



OPENING GeneralPaths.txt
------------------------------

The easiest way is to use the javax.swing.JFileChooser already implmented in JDK.
JFileChooser is a Dialog that lets the user navigate the computer (drives, folders and files) and pick either a file or a folder.

Somewhere in your code use this lines to show an Open File Dialog:

    String filename = "C:\\MyRules\\";//initial folder to show
    JFileChooser fc = new JFileChooser(new File(filename));
    // Show open dialog; this method does not return until the dialog is closed
    fc.showOpenDialog(this);
    File selFile = fc.getSelectedFile();
    //i.e filePath value "C:\MyRules\rulefile1.txt"
    String filePath = selFile.getAbsolutePath();
    System.out.println(filePath);

You can find more info here: http://www.javaalmanac.com/egs/javax.swing.filechooser/CreateDlg.html

Now that you can get the absolute path to any file, here is the whole solution to open the GeneralPaths.txt file:

String filename = "C:\\MyRules\\";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(this);
File selFile = fc.getSelectedFile(); //the user selected GeneralPaths.txt file
String filePath = selFile.getAbsolutePath();

    try{
        PropertyFile generalRulesPF = new PropertyFile(filePath);
        String rulefile1 = generalRulesPF.getKeyValue("RULEPATHS", "rulefile1");
        String rulefile2 = generalRulesPF.getKeyValue("RULEPATHS", "rulefile2");
        System.out.println(rulefile1); //Result: c:\MyRules\rulefile1.txt
        System.out.println(rulefile2); //Result: c:\MyRules\rulefile2.txt

        //MODIFY AND SAVE
        generalRulesPF.setKeyValue("RULEPATHS", "rulefile1", "put a new value here");
        generalRulesPF.save(filePath);//the file is overwritten

       }catch(Exception IOex){System.err.println(IOex.getMessage());}
   


ABOUT RUNNING YOUR APPLICATION
***************************

It's not advisable to build an .exe file to make you app runable. It would be better - and more Java like - to build a jar file a distribute it among users PCs.
If you don't know how to do it, just drop a few lines here and I'll show you how. It’s very straightforward and easy to maintain.
Finally, sorry for my english. It's not my native language!!
Hope this help you!!!
c u arround... bye!



0
 
LVL 3

Assisted Solution

by:JohnnyAffa
JohnnyAffa earned 250 total points
Comment Utility
lokimarine,

1) first of all, java is an interpreted langauge.  you cant make it an exe. ( you can with 3rd party utilities, however it defeats the purpose of java being platform independent).

2) what is your interface? command line or gui? if its command line, you can get user input using:

 BufferedReader br = new BufferedReader(System.in);

 String input = br.readLine();

if youre going to use a gui interface then create a JTextField (swing prefered) or TextField (awt) getText() method which return a string

ie

TextField textbox = new TextField();

String input = textbox.getText();

3) reading your file

File file = new File([filename]);  // where filename is a string

if ( file.exists() == true )
{
       FileInputStream fis = new FileInputStream(file);
       byte data[] = new byte[(int)file.length()];

      while ( fis.read(data,0,data.length) != -1 );  // -1 = end of file

      String file_contents = new String(data);
           
}

the above code read a file, temporarily places the contents into a byte array and then converts it to a string.  from here you can extract the field you want.

4)  extracting contents from your string use StringTokenizer

StringTokenizer token = new StringTokenizer([string],[delimter]);
String field = null;

while ( token.hasMoreTokens() == true)
   field = token.nextToken();

in you case though, you want to read a line at a time so your delimeter would be "\n" and the string would be your file

so, StringTokenizer token = new StringTokenizer(file_contents,"\n");

while ( token.hasMoreTokens() == true )
{
     String field1 = token.nextToken(" "); // gets field delimited by space
     String field2 = token.nextToken("\n"); // get field delimited by newline

}
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
changeXy challenge 13 56
array220 challenge 8 45
countPairs challenge 7 57
HashMap Vs TreeMap 12 48
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now