java - 解析 csv 文件并存储结果,因为 JFree 图表数据集消耗堆空间

标签 java csv netbeans jfreechart swingworker

我有一个 Netbeans 模块应用程序,在我的 Netbeans IDE 中执行时运行正常。 但是,当我从生成的解压缩文件夹运行分发可执行文件时,应用程序 swing 工作任务将在一段时间后停止。它循环遍历几个文件,然后停止。 我最好的猜测是我必须对处理 csv 文件的循环做一些事情?或者...任何想法或提示将不胜感激 文件的大小为 2000 - 600.000 行,包含 5 个定义为 double 的时间序列。 我将数据集存储在集合中。

这是我使用 while 循环的方法

protected XYDataset generateDataSet(String filePath) {

    TimeSeriesCollection dataset = null;
    try {
        dataset = new TimeSeriesCollection();

        boolean isHeaderSet = false;

        String fileRow;
        StringTokenizer tokenizer;
        BufferedReader br;
        List<String> headers;
        String encoding = "UTF-8";
        br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), encoding));

        //br = new BufferedReader(new FileReader(filePath));
        if (!br.ready()) {
            throw new FileNotFoundException();
        }
        fileRow = br.readLine();

循环从这里开始

        while (fileRow != null) {

            if (!isHeaderSet) {
                headers = getHeaders(fileRow);
                for (String string : headers) {
                    dataset.addSeries(new TimeSeries(string));
                }
                isHeaderSet = true;
            }
            if (fileRow.startsWith("#")) {
                fileRow = br.readLine();
            }
            String timeStamp = null;
            String theTok1 = null;
            String theTok2;
            tokenizer = new StringTokenizer(fileRow);
            if (tokenizer.hasMoreTokens()) {
                theTok1 = tokenizer.nextToken().trim();
            }
            if (tokenizer.hasMoreTokens()) {
                theTok2 = tokenizer.nextToken().trim();
                timeStamp = theTok1 + " " + theTok2;
            }

            Millisecond m = null;

            if (timeStamp != null) {
                m = getMillisecond(timeStamp);
            }

            int serieNumber = 0;
            br.mark(201);
            if (br.readLine() == null) {
                br.reset();
                while (tokenizer.hasMoreTokens()) {
                    if (dataset.getSeriesCount() > serieNumber) {
                        dataset.getSeries(serieNumber).add(m, parseDouble(tokenizer.nextToken().trim()), true);

最后一个代码行,我在最后一个 scv 文件行上将通知程序设置为 true,否则每次我添加新系列时它都会循环数据集,并且足以在最后一行执行此操作。

                    } else {
                        tokenizer.nextToken();
                    }
                    serieNumber++;
                }
            } else {
                br.reset();
                while (tokenizer.hasMoreTokens()) {
                    if (dataset.getSeriesCount() > serieNumber) {
                        dataset.getSeries(serieNumber).add(m, parseDouble(tokenizer.nextToken().trim()), false);

                    } else {
                        tokenizer.nextToken();
                    }
                    serieNumber++;
                }
            }
            fileRow = br.readLine();
        }
        br.close();
    } catch (FileNotFoundException ex) {
        printStackTrace(ex);
    } catch (IOException | ParseException ex) {
        printStackTrace(ex);
    }
    return dataset;
}

这也是我在处理从上面的代码调用的 heders 和时间戳时使用的方法。 (有时 csv 文件会丢失标题)

/**
 * If the start cahr "#" is missing then the headers will all be "NA".
 *
 * @param fileRow a row with any numbers of headers,
 * @return ArrayList with headers
 */
protected List<String> getHeaders(String fileRow) {
    List<String> returnValue = new ArrayList<>();
    StringTokenizer tokenizer;
    if (fileRow.startsWith("#")) {
        tokenizer = new StringTokenizer(fileRow.substring(1));
    } else {
        tokenizer = new StringTokenizer(fileRow);
        tokenizer.nextToken();
        tokenizer.nextToken();//date and time is one header but two tokens
        while (tokenizer.hasMoreTokens()) {
            returnValue.add("NA");
            tokenizer.nextToken();
        }
        return returnValue;
    }
    tokenizer.nextToken();
    while (tokenizer.hasMoreTokens()) {
        returnValue.add(tokenizer.nextToken().trim());
    }
    return returnValue;
}

/**
 * @param fileRow must match pattern "yyyy-MM-dd HH:mm:ss.SSS"
 * @return
 * @throws ParseException
 */
public Millisecond getMillisecond(String timeStamp) throws ParseException {
    Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(timeStamp);
    return new Millisecond(date);
}

最佳答案

假设您从 doInBackground() 的实现中调用 generateDataSet(),对 dataset 的更改通常会在后台线程上触发事件,违反了 Swing 的 single thread rule 。相反,publish() interim resultsprocess() 它们,如图 here .

关于java - 解析 csv 文件并存储结果,因为 JFree 图表数据集消耗堆空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34200566/

相关文章:

java - 从 MySQL 数据库验证散列密码

python - pandas.DataFrame.round 似乎不适用于我的 DataFrame - 舍入问题导致额外的数据存储在 csv 文件中

Powershell 哈希表导出为 CSV

java - JBoss 网站 : HTTP Status 404

java - 通过 Scanner 保证整数输入的更简单方法?

java - 将 LinkedList 值插入数据库

java - 内联 WSDL 而不是 wsdl :import

python - 如何在 Python 中使用 Pandas 数据结构 append 多个 CSV 文件

css - 如何将 CSS 文档放入 Netbeans

java - 跟踪所有方法和类