0

我正在做的是逐行读取一个文件,格式化每一行,然后写入一个新文件。但问题是文件很大,将近 178 MB。 但总是收到错误消息:IO 控制台更新程序错误,Java 堆空间。这是我的代码:

public class fileFormat {
    public static void main(String[] args) throws IOException{

        String strLine;

        FileInputStream fstream = new FileInputStream("train_final.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(fstream));
        BufferedWriter writer = new BufferedWriter(new FileWriter("newOUTPUT.txt"));

        while((strLine = reader.readLine()) != null){
            List<String> numberBox = new ArrayList<String>();
            StringTokenizer st = new StringTokenizer(strLine);
            while(st.hasMoreTokens()){
                numberBox.add(st.nextToken());
            }
            for (int i=1; i< numberBox.size(); i++){
                String head = numberBox.get(0);
                String tail = numberBox.get(i);
                String line = head + "  "+tail ;
                System.out.println(line);
                writer.write(line);
                writer.newLine();
            }
            numberBox.clear();
        }
        reader.close();
        writer.close();
    }
}

如何避免此错误消息?此外,我设置了 VM 首选项:-xms1024m

4

4 回答 4

3

删除线

System.out.println(line);

这是 fialing 控制台更新程序的解决方法,否则会耗尽内存。

于 2013-09-05T07:45:43.793 回答
0

程序看起来不错。我怀疑问题是您在 Eclipse 内部运行它,并且 System.out 由 Eclipse 在内存中收集(显示在该控制台窗口中)。

 System.out.println(line);

尝试在 Eclipse 之外运行它,将 Eclipse 设置更改为管道 System.out 某处,或删除该行。

于 2013-09-05T07:45:45.430 回答
0

这部分代码:

       for (int i=1; i< numberBox.size(); i++){
            String head = numberBox.get(0);
            String tail = numberBox.get(i);
            String line = head + "  "+tail ;
            System.out.println(line);
            writer.write(line);
            writer.newLine();
       }

可以翻译成:

       String head = numberBox.get(0);
       for (int i=1; i< numberBox.size(); i++){
            String tail = numberBox.get(i);
            System.out.print(head);
            System.out.print(" ");
            System.out.println(tail);
            writer.write(head);
            writer.write(" ");
            writer.write(tail);
            writer.newLine();
       }

这可能会增加一些代码重复,但可以避免创建大量对象。

此外,如果您将此 for 循环与构建 numberBox 的循环合并,则根本不需要 numberBox 结构。

于 2013-09-05T07:58:36.380 回答
0

如果您读取整个文件,堆内存将占据更好的选择来读取卡盘中的文件。请参阅我的以下代码。它将从参数中给出的偏移量开始读取,并返回结束偏移量。您需要传递要读取的行数。

请记住:您可以使用任何集合来存储这些读取的行,并在调用此方法读取下一个块之前清除集合。

FileInputStream fis = new FileInputStream(file);
InputStreamReader   streamReader = new InputStreamReader(fis, "UTF-8");
LineNumberReader   reader = new LineNumberReader(streamReader);

//递归调用下面的方法,直到文件没有到达末尾

public int getParsedLines(LineNumberReader reader, int iLineNumber_Start, int iNumberOfLinesToBeRead) {
    int iLineNumber_End = 0;

    int iReadUptoLines = iLineNumber_Start + iNumberOfLinesToBeRead;

    try {
        reader.mark(iLineNumber_Start);
        reader.setLineNumber(iLineNumber_Start);
        do {
            String str = reader.readLine();
            if (str == null) {
                break;
            }
            // your code


            iLineNumber_End = reader.getLineNumber();
        } while (iLineNumber_End != iReadUptoLines);
    } catch (Exception ex) {
        // exception handling
    }
    return iLineNumber_End;
}
于 2013-09-05T08:01:16.990 回答