如何在循环中选择ASCII输入文件中的列

时间:2015-09-25 06:59:06

标签: java file loops inputstream filereader

我有一个大约160行的ASCII文件(假设result.txt),其中包含以下内容:

Just a comment
with two or more lines

File title, Versionnumber

Time    Value1     Value2     Value3    Value4
(s)     (m)        (m/s)      (km)      (N)
0.002   8.000E+00  0.000E+00  0.000E+00 10.000E+01
0.040   9.850E+00  1.221E-04  0.000E+00 12.000E+01
0.060   12.780E+00 1.312E-02  0.000E+00 16.000E+05
...

我现在想要根据时间列处理每个值列。我们的想法是声明一个地图并将每个时间步的值放在其中。因此Value1的第一张地图如下所示:

0.002 -> 8.000E+00
0.040 -> 9.850E+00
0.060 -> 12.780E+00

Value2Value3,...,ValueN的地图与上面显示的分配类似。时间步长可以是double,而值可以是String(我知道如何根据我的需要转换它们)。

最简单,最快速,最有效的方法是什么?

更新:这是我阅读文件的方式:

FileInputStream fis;
try {
    fis = new FileInputStream("file.txt");
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

    String line;
    while ((line = br.readLine()) != null) {
        // split columns
        System.out.println(line);
    }
    br.close();
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
} catch (IOException e2) {
    e2.printStackTrace();
}

拆分列的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

以下是您可以用来填写已有骨架的代码:

// class level declaration
Map<Double, String> timeSeriesMap = new HashMap<Double, String>();

while ((line = br.readLine()) != null) {
    // split current line on any amount of whitespace
    String[] parts = line.trim().split("\\s+");
    Double key     = Double.valueOf(parts[0]);
    String value   = parts[1];

    // add the (key, value) pair to your Map
    timeSeriesMap.put(key, value);

    System.out.println(line);
}

答案 1 :(得分:1)

我解决了这个问题(感谢Tim Biegeleisen)。如果有人遇到同样的问题,请输入以下代码:

public void myMethod() {
    // TreeMap will sort the Map by key
    TreeMap<Double, String> map = new TreeMap<Double, String>();

    FileInputStream fis;
    try {
        fis = new FileInputStream("file.txt");
        BufferedReader br = new BufferedReader(
                new InputStreamReader(fis));

        String line;
        while ((line = br.readLine()) != null) {
            String[] parts = line.split("\t");
            if (parts.length >= 2 && isNumeric(parts[0])) {
                // remove whitespaces
                map.put(Double.parseDouble(parts[0].replaceAll(" ", "")), parts[1].replaceAll(" ", ""));
            }
        }
        br.close();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e2) {
        e2.printStackTrace();
    }
}

boolean isNumeric(String string) {
    try {
        double d = Double.parseDouble(string);
    } catch (NumberFormatException nfe) {
        return false;
    }
    return true;
}

答案 2 :(得分:0)

我个人会使用Scanner类。

然后你所要做的就是:

Scanner sc = new Scanner(fis);
while(sc.hasNextDouble()) {
    double value1 = sc.nextDouble();
    double value2 = sc.nextDouble();
    double value3 = sc.nextDouble();
    double value4 = sc.nextDouble();
    double value5 = sc.nextDouble();
    double value6 = sc.nextDouble();

    // do what you need to do
}

Oracle有一个关于如何使用扫描程序的教程,这可能很有用:

https://docs.oracle.com/javase/tutorial/essential/io/scanning.html