如何用java从一个大文件中读取并写入一个新文件

如何用java从一个大文件中读取并写入一个新文件,java,Java,我正在做的是逐行读取一个文件,格式化每一行,然后写入一个新文件。但问题是这个文件很大,将近178MB但总是收到错误消息:IO控制台更新程序错误,java堆空间。以下是我的代码: public class fileFormat { public static void main(String[] args) throws IOException{ String strLine; FileInputStream fstream = new FileInpu

我正在做的是逐行读取一个文件,格式化每一行,然后写入一个新文件。但问题是这个文件很大,将近178MB但总是收到错误消息: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();
    }
}
公共类文件格式{
公共静态void main(字符串[]args)引发IOException{
弦斯特林;
FileInputStream fstream=新的FileInputStream(“train_final.txt”);
BufferedReader reader=新的BufferedReader(新的InputStreamReader(fstream));
BufferedWriter=newbufferedwriter(newfilewriter(“newOUTPUT.txt”);
而((strLine=reader.readLine())!=null){
List numberBox=新的ArrayList();
StringTokenizer st=新的StringTokenizer(strLine);
而(st.hasMoreTokens()){
numberBox.add(st.nextToken());
}
对于(int i=1;i
如何避免此错误消息?此外,我还设置了VM首选项:-xms1024m

删除该行

System.out.println(line);
这是fialing控制台更新程序的一种解决方法,否则会耗尽内存。

删除该行

System.out.println(line);

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

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


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

程序看起来正常。我怀疑问题在于您在Eclipse内部运行了这个,并且System.out由Eclipse在内存中收集(显示在控制台窗口中)

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

这部分代码:

       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();
       }
for(int i=1;i
可翻译为:

       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();
       }
String head=numberBox.get(0);
对于(int i=1;i
这可能会增加一点代码重复,但可以避免创建大量对象

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

这部分代码:

       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();
       }
for(int i=1;i
可翻译为:

       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();
       }
String head=numberBox.get(0);
对于(int i=1;i
这可能会增加一点代码重复,但可以避免创建大量对象


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

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

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

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;
}

如果您读取整个文件,堆内存将占用,因此在chuck中读取文件是一个更好的选择。请参阅下面的代码。它将从参数中给定的偏移量开始读取,并返回结束偏移量。您需要传递要读取的行数

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

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;
}

您可以尝试刷新
BufferedWriter
@MadProgrammer:这不会导致OOM。缓冲区并没有那么大。使用RandomAccessFile怎么样?看起来这是一个eclipse问题。查看此线程:可能是由于写入system.out整个文件造成的……您可以尝试刷新
BufferedWriter
@MadProgrammer:这不应该导致OOM。缓冲区并没有那么大。使用RandomAccessFile怎么样?看起来这是一个eclipse问题。看一看这个线程:可能是因为您向system.out写入了整个文件……我复制了这个问题,删除了这一行就解决了这个问题。这是一个eclipse问题。代码工作起来就像一个符咒,没有向sysout写入代码。我重现了这个问题