Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java Scanner库解析这个最有效的方法是什么?_Java_Performance_Java.util.scanner - Fatal编程技术网

用Java Scanner库解析这个最有效的方法是什么?

用Java Scanner库解析这个最有效的方法是什么?,java,performance,java.util.scanner,Java,Performance,Java.util.scanner,我试图用Java的Scanner库解析一个大文件的一部分,但是我很难确定解析这个文本的最佳路径 SECTOR 199 FLAGS 0x1000 AMBIENT LIGHT 0.67 EXTRA LIGHT 0.00 COLORMAP 0 TINT 0.00 0.00 0.00 BOUNDBOX 7.399998 8.200002 6.199998 9.399998 8.500000 7.099998 COLLIDEBOX 7.605121 8.230770 6.200000 9.399994 8

我试图用Java的Scanner库解析一个大文件的一部分,但是我很难确定解析这个文本的最佳路径

SECTOR 199
FLAGS 0x1000
AMBIENT LIGHT 0.67
EXTRA LIGHT 0.00
COLORMAP 0
TINT 0.00 0.00 0.00
BOUNDBOX 7.399998 8.200002 6.199998 9.399998 8.500000 7.099998
COLLIDEBOX 7.605121 8.230770 6.200000 9.399994 8.469233 7.007693
CENTER 8.399998 8.350001 6.649998
RADIUS 1.106797
VERTICES 12
0: 1810
1: 1976
2: 1977
3: 1812
4: 1978
5: 1979
6: 1820
7: 1980
8: 1821
9: 1981
10: 1982
11: 1811
SURFACES 1893 8

它有一些可选字段(SOUND、collizebox),因此我无法像处理文件的前一部分那样按特定顺序进行解析。我不确定如何在不让它变得非常低效的情况下进行此操作,目前我一直在考虑解析每一行,然后用字符串将其拆分。拆分(“\s+”)以获取值,但我很好奇我还有什么其他选项:\

输入看起来非常复杂,足以支持一个完整的解析器。我建议使用一个库,比如ANTLR()。

输入看起来很复杂,足以支持一个完整的解析器。我建议使用ANTLR()之类的库。

我首先用关键字定义一个枚举,如:

 public enum Keyword {SECTOR, FLAGS, AMBIENT, EXTRA, COLORMAP, TINT, 
    BOUNDBOX, COLLIDEBOX, CENTER, RADIUS, VERTICES, SURFACES}
解析可以逐行进行,以空格字符进行拆分。然后,我将第一个元素从关键字类转换为枚举,并使用一个简单的开关构造来处理值:

public Model parse(List<String> lines) {

   Model model = new Model();

   Iterator<String> it = lines.iterator();
   while(it.hasNext()) {
      String[] elements = it.next().split("\s+");

      switch(Keyword.valueOf(elements[0])) {
        case SECTOR: model.addSector(elements[1]); break;
        case FLAGS: model.addFlags(elements[1]); break;
        // ...
        case VERTICES:
          int numberOfVertices = Integer.parseInt(elements[1]);
          for (int i = 0; i < numberOfVertices; i++) {
             elements = it.next().split("\s+");
             model.addVertice(i, elements[1]);
          }
          break;
        case default:
          // handle malformed line

      }
   }
   return model;
}
公共模型解析(列表行){
模型=新模型();
迭代器it=lines.Iterator();
while(it.hasNext()){
String[]elements=it.next().split(“\s+”);
开关(关键字.valueOf(元素[0])){
案例扇区:model.addSector(元素[1]);break;
案例标志:model.addFlags(元素[1]);break;
// ...
案例顶点:
int numberoftexts=Integer.parseInt(元素[1]);
对于(int i=0;i
我首先用关键字定义一个枚举,如:

 public enum Keyword {SECTOR, FLAGS, AMBIENT, EXTRA, COLORMAP, TINT, 
    BOUNDBOX, COLLIDEBOX, CENTER, RADIUS, VERTICES, SURFACES}
解析可以逐行进行,以空格字符进行拆分。然后,我将第一个元素从关键字类转换为枚举,并使用一个简单的开关构造来处理值:

public Model parse(List<String> lines) {

   Model model = new Model();

   Iterator<String> it = lines.iterator();
   while(it.hasNext()) {
      String[] elements = it.next().split("\s+");

      switch(Keyword.valueOf(elements[0])) {
        case SECTOR: model.addSector(elements[1]); break;
        case FLAGS: model.addFlags(elements[1]); break;
        // ...
        case VERTICES:
          int numberOfVertices = Integer.parseInt(elements[1]);
          for (int i = 0; i < numberOfVertices; i++) {
             elements = it.next().split("\s+");
             model.addVertice(i, elements[1]);
          }
          break;
        case default:
          // handle malformed line

      }
   }
   return model;
}
公共模型解析(列表行){
模型=新模型();
迭代器it=lines.Iterator();
while(it.hasNext()){
String[]elements=it.next().split(“\s+”);
开关(关键字.valueOf(元素[0])){
案例扇区:model.addSector(元素[1]);break;
案例标志:model.addFlags(元素[1]);break;
// ...
案例顶点:
int numberoftexts=Integer.parseInt(元素[1]);
对于(int i=0;i
这种方法怎么样:

find next command (SECTOR, FLAGS, AMBIENT LIGHT, EXTRA LIGHT, etc)
no command found? -> output error and stop
map to command implementation 
execute command (pass it the scanner and your state holder)
command impl handles specific reading of arguments
rinse, repeat,...
您必须创建一个命令界面:

public interface Command {
    String getName();
    void execute(Scanner in, ReadState state);
}
以及针对您可能遇到的每种命令类型的单独实现:

public class SectorCommand implements Command {
    public String getName() {
        return "SECTOR";
    }
    public void execute(Scanner in, ReadState state) {
        state.setSector(in.nextInt());
    }
}
以及某种类型的工厂来查找命令:

public class CommandFactory {

    private Map<String, Command> commands;
    public CommandFactory() {
        commands = new HashMap<String, Command>();
        addCommand(new SectorCommand());
        // add other commands
    }
    public Command findCommand(Scanner in) {
        for (Map.Entry<String, Command> entry : commands.entrySet()) {
            if (in.findInLine(entry.getKey())) {
                return commands.get(entry.getValue);
            }
        }
        throw new IllegalArgumentException("No command found");
    }
    private void addCommand(Command command) {
        commands.put(command.getName(), command); 
    }
}
公共类CommandFactory{
专用地图命令;
公共命令工厂(){
commands=newhashmap();
addCommand(新的SectorCommand());
//添加其他命令
}
公共命令findCommand(扫描仪输入){
for(Map.Entry:commands.entrySet()){
if(在.findInLine(entry.getKey())中){
返回命令.get(entry.getValue);
}
}
抛出新的IllegalArgumentException(“未找到命令”);
}
私有void addCommand(Command命令){
commands.put(command.getName(),command);
}
}

(此代码可能无法编译)

此方法如何:

find next command (SECTOR, FLAGS, AMBIENT LIGHT, EXTRA LIGHT, etc)
no command found? -> output error and stop
map to command implementation 
execute command (pass it the scanner and your state holder)
command impl handles specific reading of arguments
rinse, repeat,...
您必须创建一个命令界面:

public interface Command {
    String getName();
    void execute(Scanner in, ReadState state);
}
以及针对您可能遇到的每种命令类型的单独实现:

public class SectorCommand implements Command {
    public String getName() {
        return "SECTOR";
    }
    public void execute(Scanner in, ReadState state) {
        state.setSector(in.nextInt());
    }
}
以及某种类型的工厂来查找命令:

public class CommandFactory {

    private Map<String, Command> commands;
    public CommandFactory() {
        commands = new HashMap<String, Command>();
        addCommand(new SectorCommand());
        // add other commands
    }
    public Command findCommand(Scanner in) {
        for (Map.Entry<String, Command> entry : commands.entrySet()) {
            if (in.findInLine(entry.getKey())) {
                return commands.get(entry.getValue);
            }
        }
        throw new IllegalArgumentException("No command found");
    }
    private void addCommand(Command command) {
        commands.put(command.getName(), command); 
    }
}
公共类CommandFactory{
专用地图命令;
公共命令工厂(){
commands=newhashmap();
addCommand(新的SectorCommand());
//添加其他命令
}
公共命令findCommand(扫描仪输入){
for(Map.Entry:commands.entrySet()){
if(在.findInLine(entry.getKey())中){
返回命令.get(entry.getValue);
}
}
抛出新的IllegalArgumentException(“未找到命令”);
}
私有void addCommand(Command命令){
commands.put(command.getName(),command);
}
}

(此代码可能无法编译)

如果文件很大,我建议您可以使用java.io.RandomAccessFile,它可以跳过您想要解析的任何区域,而且速度非常快。若将整个文件映射到memnory,可能会降低应用程序的速度


也可以使用java.util.StringTokenizer拆分简单的大小写。例如,空格、逗号等。它比正则表达式快。

如果文件很大,我建议您可以使用java.io.RandomAccessFile,它可以跳过您想要解析的任何区域,而且速度非常快。若将整个文件映射到memnory,可能会降低应用程序的速度


也可以使用java.util.StringTokenizer拆分简单的大小写。例如,空格、逗号等。它比正则表达式快。

可能必须采用这种方法,尽管我不知道是否需要“重写”我的代码:已经在这方面投入了很多时间,但是谢谢你的建议3我可能不得不走这条路,但我不知道是否要“重写”我的代码:已经在这方面投入了很多时间,但是谢谢你的建议3我喜欢这件的外观。干净、简单,并且已经检查了格式错误的文件。我现在可以用它来测试。我喜欢它的外观。干净、简单,并且已经检查了格式错误的文件。我现在可以使用它,用于测试目的。