For loop 在计算txt文件中的字符串时出现问题

For loop 在计算txt文件中的字符串时出现问题,for-loop,heap,filereader,fileutils,For Loop,Heap,Filereader,Fileutils,我正在开发一个程序,它读取一个文本文件并创建一个报告。报告的内容如下:文件中每个字符串的编号、其“状态”以及每个字符串开头的一些符号。它可以很好地处理高达100 Mb的文件 但是,当我使用大于1,5Gb的输入文件运行程序,并且包含超过100000行时,我得到以下错误: > Exception in thread "main" java.lang.OutOfMemoryError: Java heap space > at java.util.Arrays.copyOfRange(Un

我正在开发一个程序,它读取一个文本文件并创建一个报告。报告的内容如下:文件中每个字符串的编号、其“状态”以及每个字符串开头的一些符号。它可以很好地处理高达100 Mb的文件

但是,当我使用大于1,5Gb的输入文件运行程序,并且包含超过100000行时,我得到以下错误:

> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
> at java.util.Arrays.copyOfRange(Unknown Source) at
> java.lang.String.<init>(Unknown Source) at
> java.lang.StringBuffer.toString(Unknown Source) at
> java.io.BufferedReader.readLine(Unknown Source) at
> java.io.BufferedReader.readLine(Unknown Source) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:771) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:723) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:745) at
> org.apache.commons.io.FileUtils.readLines(FileUtils.java:1512) at
> org.apache.commons.io.FileUtils.readLines(FileUtils.java:1528) at
> org.apache.commons.io.ReadFileToListSample.main(ReadFileToListSample.java:43)
>线程“main”java.lang.OutOfMemoryError中出现异常:java堆空间
>位于java.util.Arrays.copyOfRange(未知源)
>java.lang.String.(未知源代码)位于
>位于的java.lang.StringBuffer.toString(未知源)
>位于的java.io.BufferedReader.readLine(未知源)
>位于的java.io.BufferedReader.readLine(未知源)
>org.apache.commons.io.IOUtils.readLines(IOUtils.java:771)位于
>org.apache.commons.io.IOUtils.readLines(IOUtils.java:723)位于
>org.apache.commons.io.IOUtils.readLines(IOUtils.java:745)位于
>org.apache.commons.io.FileUtils.readLines(FileUtils.java:1512)位于
>org.apache.commons.io.FileUtils.readLines(FileUtils.java:1528)位于
>org.apache.commons.io.ReadFileToListSample.main(ReadFileToListSample.java:43)
我将VM参数增加到-Xms128m-Xmx1600m(在eclipse运行配置中),但这并没有帮助。来自OTN论坛的专家建议我读一些书,提高我的程序的性能。谁能帮我改进一下吗?多谢各位

代码:

import org.apache.commons.io.FileUtils;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.FileReader;
导入java.io.IOException;
导入java.io.LineNumberReader;
导入java.io.PrintStream;
导入java.util.List;
公共类ReadFileToList{
公共静态void main(字符串[]args)引发FileNotFoundException
{
File File\u out=新文件(“D:\\Docs\\test\u out.txt”);
FileOutputStream fos=新的FileOutputStream(文件输出);
打印流ps=新打印流(fos);
系统放样(ps);
//创建一个文件对象
File File=新文件(“D:\\Docs\\test\u in.txt”);
FileReader fr=null;
LineNumberReader lnr=null;
试一试{
//这里我们使用FileUtils读取一个文件sample.txt
//使用FileUtils.readLines()的公用io类
//我们可以逐行读取文件内容并返回
//结果将显示为字符串列表。
列表内容=FileUtils.readLines(文件);
//
//迭代结果以打印文件的每一行。
fr=新文件读取器(文件);
lnr=新的行号读取器(fr);
for(字符串行:内容)
{
String begin_line=line.substring(0,38);//从字符串返回38个字符
字符串begin_line_,不带_null=begin_line。替换(“\u0000”,”);
字符串begin_line_without_null_spaces=begin_line_without_null.replaceAll(“+”,”);
int stringlenght=line.length();
line=lnr.readLine();
int line_num=lnr.getLineNumber();
字符串状态;
//if的正确长度
int c_____________f=12;
int c_ea_length_f=13;
整数c_a_长度f=2130;
int c____________e=3430;
int c_ea_e=1331;
整数c_a_长度e=442;
int h_ext=6;
int t_ext=6;
如果(StringLength==c\u\u长度||
StringLength==c_ea_length_f||
StringLength==c_a_length_f||
StringLength==c____长度||
StringLength==c_ea_length_e||
StringLength==c_a_length_e||
stringlenght==h_ext||
stringlenght==t_ext)
status=“ok”;
else status=“失败”;
System.out.println(+line_num+stringlength+status+begin_line_,不带空格);
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
OTN的专家还说,这个程序打开输入并读取两次。“for statement”中可能有一些错误?但是我找不到它。
谢谢。

您在循环中声明变量,并且做了很多非必需的工作,包括读取文件两次,这对性能也没有好处。可以使用行号读取器获取行号和文本,并重用行变量(在循环外部声明)。这里有一个简短的版本,可以满足您的需要。您需要完成validLength方法来检查所有的值,因为我只包含了前两个测试

import java.io.*;

public class TestFile {

//a method to determine if the length is valid implemented outside the method that does the reading
    private static String validLength(int length) {
        if (length == 12 || length == 13 || length == 2130) //you can finish it
            return "ok";
        return "fail";
    }

    public static void main(String[] args) {
        try {
            LineNumberReader lnr = new LineNumberReader(new FileReader(args[0]));
            BufferedWriter out = new BufferedWriter(new FileWriter(args[1]));
            String line;
            int length;
            while (null != (line = lnr.readLine())) {
                length = line.length();
                line = line.substring(0,38);
                line = line.replace("\u0000", " ");
                line = line.replace("+", " ");
                out.write( lnr.getLineNumber() + length + validLength(length) + line);
                out.newLine();
            }
            out.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

将其称为java测试文件D:\Docs\test\u in.txt D:\Docs\test\u in.txt,或者如果要硬编码,请将args[0]和args[1]替换为文件名

不一次读取整个文件怎么样?代码'line=lnr.readLine;'就是你第二次读这行的地方。您已经在foreach循环中,从“content”中读取了行。如果文件很大,如果您遇到OutOfMemoryError,我会将文件分成多个部分,显然您正在加载的文件太大。Justin,如果我在报告中收到的代码中注释line“//line=lnr.readLine();”:
String№ 0的长度为912,状态为:失败,字符串开始-->(换行符)字符串№ 0的长度为3031,状态为:失败,字符串开始-->(换行符)字符串№ 0的长度为4762,状态为:失败,字符串开头-->
您能为我的(Karakuricoder)代码创建接口表单推荐一些阅读资料吗?您好,5月12日,谢谢。我不确定我是否理解您的问题-您想创建用户界面还是Java类界面?如果是用户界面,请使用Google并键入“java swing教程”,然后从Oracle/Sun.user interface中选择一个教程。好啊我明白了。再次感谢你。
import java.io.*;

public class TestFile {

//a method to determine if the length is valid implemented outside the method that does the reading
    private static String validLength(int length) {
        if (length == 12 || length == 13 || length == 2130) //you can finish it
            return "ok";
        return "fail";
    }

    public static void main(String[] args) {
        try {
            LineNumberReader lnr = new LineNumberReader(new FileReader(args[0]));
            BufferedWriter out = new BufferedWriter(new FileWriter(args[1]));
            String line;
            int length;
            while (null != (line = lnr.readLine())) {
                length = line.length();
                line = line.substring(0,38);
                line = line.replace("\u0000", " ");
                line = line.replace("+", " ");
                out.write( lnr.getLineNumber() + length + validLength(length) + line);
                out.newLine();
            }
            out.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}