使用StreamTokenizer读取结构化文件

时间:2012-03-20 01:35:17

标签: java tokenize

如果我有一个具有某种结构的文件:

type
2
0 0 name
100 100 name
1
1 2 name name

如何使用StreamTokenizer处理此文件?这是程序方法的唯一方法吗?

StreamTokenizer st = new StreamTokenizer(new FileReader(filename));

if (st.nextToken() != StreamTokenizer.TT_EOF) {
    st.nextToken();
    if (st.sval == "typea") {
        st.nextToken();

        int i = (int) st.nval;
        if (i > 0) {
            while (i > 0) {
                // process node sets
            }
        }
    } else if (st.sval == "typeb") {
        st.nextToken();

        int i = (int) st.nval;
        if (i > 0) {
            while (i > 0) {
                // process node sets
            }
        }
    }
}

如果存在意外的令牌,可以跳过。

2 个答案:

答案 0 :(得分:1)

StreamTokenizer的大部分功能已被Scanner类所取代,我相信在继续之前值得一看。

答案 1 :(得分:1)

您可能需要以程序方式执行此操作。考虑将事物分解为单独的函数并在进行时收集节点集。这是一个简单的解析你给出的例子。随着事情变得更加复杂,你可以在它上面构建。我相信别人可以为你提供更好的东西。

import java.util.Formatter;
import java.util.Collections;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static java.io.StreamTokenizer.*;


public class NodeToker {

   public static void main(String[] args) throws IOException  {
      final String fname = "/data/types.txt";
      InputStream stream = Class.class.getResourceAsStream(fname);

      if (stream == null) {
         System.err.println("Could not open stream " + fname);
      } else {
         NodeToker typeToker = new NodeToker();
         AllTypes allTypes = typeToker.parse(stream);

         try { stream.close(); }
         catch (IOException ex) { }

         Formatter fmtr = new Formatter(System.out);

         int groupCount = 0;
         for (NodeSet nodeSet : allTypes) {
            groupCount++;
            int nodeCount = 0;
            for (Node node : nodeSet) {
               fmtr.format("Set %s, Node %s: %s%n",
                       groupCount, ++nodeCount, node);
            }
         }
      }
   }

   public AllTypes parse(InputStream stream) throws IOException {
      Reader reader = new BufferedReader(new InputStreamReader(stream));

      StreamTokenizer tok = new StreamTokenizer(reader);
      setupToker(tok);

      AllTypes allTypes = new AllTypes();

      while (tok.nextToken() != TT_EOF) {
         String text = tok.sval == null ? "" : tok.sval;

         if (text.startsWith("type")) {
            // slurp newline
            tok.nextToken();
            handleNodeSet(tok, allTypes);
         }
      }

      return allTypes;
   }

   private void handleNodeSet(
           StreamTokenizer tok,
           AllTypes allTypes) throws IOException {
      while (tok.nextToken() != TT_EOF) {
         if (tok.ttype == TT_NUMBER) {
            final int numRows = (int) tok.nval;
            tok.nextToken();

            NodeSet nodeSet = allTypes.newNodeSet();

            for (int i = 0; i < numRows; i++) {
               Node node = nodeSet.newNode();
               handleNode(tok, node);
            }
         } else {
            // maybe beginning of next type?
            tok.pushBack();
            break;
         }
      }
   }

   private void handleNode(StreamTokenizer tok,
           Node node) throws IOException {
      while (!endOfRow(tok)) {
         if (tok.ttype == TT_NUMBER) {
            node.addNumber((int)tok.nval);
         } else if (tok.ttype == TT_WORD) {
            node.addName(tok.sval);
         }
      }
   }

   private void setupToker(StreamTokenizer tok) {
      tok.eolIsSignificant(true);
   }

   private boolean endOfRow(StreamTokenizer tok) throws IOException {
      return (tok.nextToken() == TT_EOL) || (tok.ttype == TT_EOF);
   }

   public static class AllTypes implements Iterable<NodeSet> {
      private List<NodeSet> typesList = new ArrayList<NodeSet>();

      public NodeSet newNodeSet() {
         NodeSet typeGroup = new NodeSet();
         typesList.add(typeGroup);
         return typeGroup;
      }

      public Iterator<NodeSet> iterator() {
         return Collections.unmodifiableCollection(typesList).iterator();
      }

   }

   public static class NodeSet implements Iterable<Node> {
      private List<Node> nodeList = new ArrayList<Node>();

      public Node newNode() {
         Node node = new Node();
         nodeList.add(node);
         return node;
      }

      public Iterator<Node> iterator() {
         return Collections.unmodifiableCollection(nodeList).iterator();
      }

   }

   public static class Node {
      private List<Integer> numbers = new ArrayList<Integer>();
      private List<String> names = new ArrayList<String>();

      public void addName(String name) {
         names.add(name);
      }

      public void addNumber(int number) {
         numbers.add(number);
      }

      @Override
      public String toString() {
         return "Node{" + "numbers=" + numbers + " names=" + names + '}';
      }
   }
}