如何在JAVA中快速读取文件中的双精度

时间:2017-07-21 07:55:26

标签: java string io double

我有很多小文件包含一些数字,就像这样。

enter image description here

我需要读取第一和第二个双打,为此我使用BufferedReader来读取并溢出它们,但它非常慢。我想知道是否还有其他方法可以更快地做到这一点?

File ifile = new File(dataFile);
FileReader ifr=new FileReader(ifile);
BufferedReader br = new BufferedReader(ifr);
br.readLine();
List<Double> ix = new ArrayList<Double>(1000);
List<Double> iy = new ArrayList<Double>(1000);
for (String sLine = br.readLine(); sLine != null && sLine != ""; sLine = br.readLine()) {
    String[] tmp = sLine.split(" ");
    double x = Double.parseDouble(tmp[0]);
    double y = Double.parseDouble(tmp[1]);
    ix.add(x);
    iy.add(y);
}
br.close();

2 个答案:

答案 0 :(得分:1)

请找到代码中提到的java文档。

package com.learning.stackoverflow;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import static com.google.common.base.MoreObjects.firstNonNull;

/**
 * {@link FileReader} accept file name and returns
 * first and second column value per line in the embeded object {@link RequiredData}
 * when <code>getDoubleValuesPerLine()</code> is called
 */
public class FileReader {
    private final String completeFilePath;
    private final List<RequiredData> requiredDataList;

    public FileReader(String completeFilePath) {
        this.completeFilePath = completeFilePath;
        this.requiredDataList = new ArrayList<>();
    }

    /**
     * Method getDoubleValuesPerLine() will return first and
     * second double values in the embeded object {@link RequiredData}
     *
     * @return
     */
    public List<RequiredData> getDoubleValuesPerLine() {
        try (Stream<String> stream = Files.lines(Paths.get(this.completeFilePath))) {
            stream.forEach(this::readDataFromStringLine);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return requiredDataList;
    }

    private void readDataFromStringLine(String stringLine) {
        String[] independentValues = firstNonNull(stringLine.trim(), "").split(" ");
        requiredDataList.add(new RequiredData(Double.valueOf(independentValues[0]), Double.valueOf(independentValues[1])));
    }

    public class RequiredData {
        private final Double firstColumn;
        private final Double secondColumn;

        public RequiredData(Double firstColumn, Double secondColumn) {
            this.firstColumn = firstColumn;
            this.secondColumn = secondColumn;
        }

        public Double getFirstColumn() {
            return firstColumn;
        }

        public Double getSecondColumn() {
            return secondColumn;
        }
    }
}

答案 1 :(得分:0)

这里可能发生的一个小修改是,不是分割整行,而是获取数组并从该数组中读取;你可以使用正则表达式获得最初的两个双精度值。

如果读取的字符串非常大,这可能会提高性能。

...
...
Pattern pattern = Pattern.compile("^([\\d.-]*)\\s([\\d.-]*)");
for (String sLine = br.readLine()) {
    Matcher matcher = pattern.matcher(sLine);
    if (matcher.matches()) {
        double x = Double.parseDouble(matcher.group(1));
        double y = Double.parseDouble(matcher.group(2));
        ix.add(x);
        iy.add(y);
    }
}
...
...

如果模式与该行匹配,您也可以跳过空行检查和其他验证作为内部代码。

此处使用的正则表达式演示:https://regex101.com/r/gqHAWs/1