0

I am receiving a packet such as

"c~ ¹" M:0013A20040559361 Ax:48 Ay:10 Az:1012 Tp:25 B:45 ? Tm:Wednesday, 02/01/13 - 16:16.57 Sº~"

and others characters which could not be pasted. I have to read the values after the colons. For example, M: , Ax:, Ay: and store it or draw it in a graph. I know of two ways: StreamTokenizer or simple java logic. The problem is I have tried both, but still I receive too many errors while reading the values. Plus, I tried a string garbage collector, its not working also.

Below are the code for both:

if(message2.contains("Ax:"))
    {
    int index = message2.indexOf("Ax:");
    String Ax = message2.substring(index+3);
    ChartAcceleration.tsAx.addOrUpdate(new Millisecond(), Double.valueOf(Ax));
    }

StreamTokenizer Code:

StreamTokenizer st = new StreamTokenizer(
                new StringReader(message));

         boolean eof = false;
        while(st.nextToken() != StreamTokenizer.TT_EOF){

              int token = st.nextToken();
              switch (token) {
                 case StreamTokenizer.TT_WORD:
                     String word = st.sval;
                     if(word.contains("Ax"))
                     {
                         Ax = true;
                     }
                     else
                         if(word.contains("Ay"))
                     {
                         Ay = true;
                     }
                         else
                             if(word.contains("Az"))
                         {
                             Az = true;
                         }
                             else
                                 if(word.contains("P"))
                             {
                                 P = true;

                             }
                                 else
                                     if(word.contains("B"))
                                 {
                                     B = true;
                                 }
                                     else
                                         if(word.contains("Tp"))
                                     {
                                         Tp = true;
                                        }
                                         else
                                         {
                                             Ax = false;
                                             Ay = false;
                                             Az = false;
                                             P = false;
                                             B = false;
                                             Tp = false;
                                         }
                 //   System.out.println("Word: " + word);
                    break;
                 case StreamTokenizer.TT_NUMBER:
                     double number = st.nval;
                     if(Ax)
                     {
                         Ax = false;
                    //   errorChecker(AxStr,number);
                        AxStr = number;
                         Sender.publishAccelerator("Ax:" + String.valueOf(AxStr));
                     }
                     else
                         if(Ay)
                         {
                             Ay = false;
                             AyStr = number;
                             Sender.publishAccelerator("Ay:"+String.valueOf(AyStr));
                         }
                         else if(Az)
                         {
                             Az = false;
                             AzStr = number;
                             Sender.publishAccelerator("Az:"+String.valueOf(AzStr));
                            // System.out.println("Az:"+AzStr);

                         }
                         else
                            if(P)
                                 {
                                     P = false;
                                     PStr = number;
                                     Sender.publishPressure(String.valueOf(PStr));
                                     //System.out.println("P:"+PStr);

                                 }
                                 else
                                     if(B)
                                     {
                                         B = false;
                                         BStr = number;
                                         Sender.publishBattery(String.valueOf(BStr));
                                     }
                                     else
                                         if(Tp)
                                         {
                                             Tp = false;
                                             TpStr = number;
                                             Sender.publishTemp(String.valueOf(TpStr));
                                         }
                    break;

                 default:
              }
        }
5
  • Can't you use a REGEX with 2 groups, one that returns what is betfore ':' and the second group to return the value? Commented Jun 21, 2013 at 7:22
  • 1
    What is "a string garbage collector"? Commented Jun 21, 2013 at 7:34
  • Are you sure you're not having problems with character encoding? What kind of "errors" do you get? Commented Jun 21, 2013 at 7:56
  • Are you sure the data is string, and not a byte stream? Commented Jun 21, 2013 at 8:24
  • The errors are incorrect values or sometimes exceptions. Well I read it through bytes but I have to show it in a String, As this is received from another device. Commented Jun 21, 2013 at 9:39

1 Answer 1

1

I put together a string parsing program for your text.

You define the tokens and end tokens that you want to parse.

Here are my results.

Ay: 10
Az: 1012
Tp: 25
B: 45
Ax: 48
Tm: Wednesday, 02/01/13 - 16:16.57

And here's the parsing code.

import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

public class StringParsing {

    private String[][] tokens = { {"Ax:", " "}, 
            {"Ay:", " "}, {"Az:", " "}, {"Tp:", " "}, {"B:", " "},
            {"Tm:", " Sº"} };

    public Properties parseString(String s) {
        Properties p = new Properties();

        for (int i = 0; i < tokens.length; i++) {
            String value = getValue(s, tokens[i][0], tokens[i][1]);
            p.setProperty(tokens[i][0], value);
        }
        return p;
    }

    private String getValue(String s, String token, String endToken) {
        int sPos = s.indexOf(token);
        if (sPos >= 0) {
            int ePos = s.indexOf(endToken, sPos + 1);
            if (ePos > sPos) {
                sPos += token.length();
                return s.substring(sPos, ePos);
            }
        }
        return "";
    }


    public static void main(String[] args) {
        String s = "c~ ¹\" M:0013A20040559361 Ax:48 Ay:10 Az:1012 " + 
                "Tp:25 B:45 ? Tm:Wednesday, 02/01/13 - 16:16.57 Sº~";

        StringParsing parsing = new StringParsing();
        Properties p = parsing.parseString(s);

        Set<Object> keys = p.keySet();
        Iterator<Object> iter = keys.iterator();

        while(iter.hasNext()) {
            String key = (String) iter.next();
            String value = p.getProperty(key);
            System.out.println(key + " " + value);
        }
    }

}

Edited to add code in response to a comment.

I haven't tested this, since I don't have a file of your data, but here's how you load a Map. The important thing is that you have to create a new Properties object for each Map entry, because the map contains a pointer to the Properties object.

   public void processStrings() {
        Map<String, Properties> dataMap = new TreeMap<String, Properties>(); 
        StringParsing parsing = new StringParsing();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(
                    "dataFile.txt"));
            String line = "";
            while ((line = reader.readLine()) != null) {
                Properties p = parsing.parseString(line);
                dataMap.put(p.getProperty("M:"), p);
            }
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. It is more efficient then what I was doing.
I am facing an issue over here. I am now reading different devices, which has different values for M: (MACs), then I store each MAC in a HashMap with a key, then I send this data to graphs, dials,...etc with the corresponding key from the HashMap. The problem is the data mixes, like wrong keys are attached to the data. Any suggestion how can I over come this? Thanks!
You can also see that the code produces Ax later but it appears before in the string.
@user1109443: Properties in a Properties instance are not guaranteed to be in any order. You ask for a property value by passing the key. As far as your other question, a HashMap<String, Properties> should work.
@user1109443: I decided a TreeMap would be better, since it would sort by M values. Check out the updated answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.