我正在做的是逐行读取一个文件,格式化每一行,然后写入新文件。但问题是文件很大,接近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
答案 0 :(得分:3)
删除行
System.out.println(line);
这是一个解决方案,它可能会耗尽内存控制台更新程序。
答案 1 :(得分:0)
程序看起来还不错。我怀疑问题是你在Eclipse中运行它,并且Eclipse在内存中收集了System.out(将显示在该控制台窗口中)。
System.out.println(line);
尝试在Eclipse之外运行它,将Eclipse设置更改为管道System.out,或删除该行。
答案 2 :(得分: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结构。
答案 3 :(得分:0)
如果您读取整个文件,堆内存将占用更好的选项来读取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;
}