【问题标题】:Text file parsing using java, suggestions needed on which one to use使用java解析文本文件,需要使用哪一个的建议
【发布时间】:2011-01-17 21:01:37
【问题描述】:

我可以使用 InputFileStream 和 Scanner 类成功读取文本文件。这很容易,但我需要做一些比这更复杂的事情。首先介绍一下我的项目的背景知识。我有一个带传感器的设备,我正在使用记录器,它将每 10 秒从传感器记录一次数据到一个文本文件中。每 10 秒就有一个新的数据行。所以我想要的是当我读取文件时将每个单独的传感器数据抓取到一个数组中。例如: 速度高度纬度经度

22 250 46.123245 122.539283

25 252 46.123422 122.534223

所以我需要将高度数据 (250, 252) 抓取到数组 alt[];等等 vel[]、lat[]、long[]...

那么文本文件的最后一行将有不同的信息,只有一行。它将包含日期、行驶距离、经过的时间..

所以在做了一些研究之后,我遇到了 InputStream、Reader、StreamTokenizer 和 Scanner 类。我的问题是你会为我的情况推荐哪一个?在我的情况下可以做我需要做的事情吗?它是否能够检查文件的最后一行是什么,以便它可以获取日期、距离等。谢谢!

【问题讨论】:

    标签: java text-parsing readfile


    【解决方案1】:

    Reader + String.split()

    String line;
    String[] values;
    BufferedReader reader = new BufferedReader(new FileReader(args[0]));
    List<Integer> velocity = new ArrayList<Integer>();
    List<Integer> altitude = new ArrayList<Integer>();
    List<Float> latitude = new ArrayList<Float>();
    List<Float> longitude = new ArrayList<Float>();
    
    while (null != (line = reader.readLine())) {
        values = line.split(" ");
        if (4 == values.length) {
            velocity.add(Integer.parseInt(values[0]));
            altitude.add(Integer.parseInt(values[1]));
            latitude.add(Float.parseFloat(values[2]));
            longitude.add(Float.parseFloat(values[3]));
        } else {
            break;
        }
    }
    

    如果您需要不列出的数组:

    velocity.toArray();
    

    据我所知,数据行有 4 项,最后一行有 3 项(日期、距离、经过的时间)

    【讨论】:

    • 其实arraylists更适用于我需要的东西。谢谢,我会试试这个,看起来正是我需要的..
    【解决方案2】:

    我会使用扫描仪。看看例子here。另一种选择是使用 BufferedReader 读取一行,然后使用 parse 方法将该行解析为所需的标记。

    您也可能会发现这个thread 很有用。

    基于上面链接的非常快速的代码。输入数组包含您的文件数据标记。

    public static void main(String[] args) {
        BufferedReader in=null;
        List<Integer> velocityList = new ArrayList<Integer>(); 
        List<Integer> altitudeList = new ArrayList<Integer>();
        List<Double> latitudeList = new ArrayList<Double>();
        List<Double> longitudeList = new ArrayList<Double>(); 
        try {
            File file = new File("D:\\test.txt");
            FileReader reader = new FileReader(file);
            in = new BufferedReader(reader);
            String string;
            String [] inputs;
            while ((string = in.readLine()) != null) {
                inputs = string.split("\\s");
                //here is where we copy the data from the file to the data stucture
                if(inputs!=null && inputs.length==4){
                    velocityList.add(Integer.parseInt(inputs[0]));
                    altitudeList.add(Integer.parseInt(inputs[1]));
                    latitudeList.add(Double.parseDouble(inputs[2]));
                    longitudeList.add(Double.parseDouble(inputs[3]));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                if(in!=null){
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //here are the arrays you want!!!
        Integer [] velocities = (Integer[]) velocityList.toArray();
        Integer [] altitiudes = (Integer[]) altitudeList.toArray();
        Double [] longitudes = (Double[]) longitudeList.toArray();
        Double [] latitudes = (Double[]) latitudeList.toArray();
    }
    

    【讨论】:

    • 谢谢.. 但我将如何申请我需要的东西?在提供的链接的最后一个示例中,它查找下一个数据类型(int,string).. 如果我有 string,int,int,int,float,float..
    • 如果您处理不同的数据类型,Scanner 类非常有用。在您的情况下,数据总是数字吗?
    • 数据将是 int 或 float.. 我没有包括我的所有数据,但我也会有时间和时间流逝我都想成为 'String'
    • Scanner 有一个方法 findInLine(String string),我可以用它来抓取我的最后一行,如果我将使用一个符号来开始该行,比如 '%'。 findInLine('%')?所以它应该抓住符号后面的线?剩下的数据怎么办?
    • 为了将它们转换为 Ineger 或 Double 你可以做 Integer.parseInt(inputs[i]);或 Double.parseDouble(inputs[i]);
    【解决方案3】:

    由于您的数据相对简单,BufferedReaderStringTokenizer 应该可以解决问题。您必须提前阅读一行才能检测到何时没有更多行了。

    你的代码可能是这样的

          BufferedReader reader = new BufferedReader( new FileReader( "your text file" ) );
    
          String line = null;
          String previousLine = null;
    
          while ( ( line = reader.readLine() ) != null ) {
              if ( previousLine != null ) {
                 //tokenize and store elements of previousLine
              }
              previousLine = line;
          }
          // last line read will be in previousLine at this point so you can process it separately
    

    但是你如何处理这条线本身真的取决于你,如果你觉得更舒服,你可以使用Scanner

    【讨论】:

    • 你可以用String.split()代替StringTokenizer,比如String[] fields = previousLine.split(" ")
    • StringTokenizer.. 它会将每个元素都转换为字符串吗?我需要一个整数数组和浮点数..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 2023-03-25
    • 2013-09-01
    • 1970-01-01
    • 2015-09-04
    相关资源
    最近更新 更多