2012-03-26 5 views
0

텍스트 파일을 읽고 보고서를 만드는 프로그램을 개발 중입니다. 보고서의 내용은 파일의 모든 문자열 수, 해당 "상태"및 시작되는 모든 문자열의 일부 기호입니다. 최대 100MB의 파일로도 잘 작동합니다.txt 파일에서 문자열 계산 중 문제가 발생했습니다.

하지만 크기가 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) 

내가 -Xms128m하는 VM 인수를 증가를 -Xmx1600m (이클립스 실행 구성에서)하지만 도움이되지 않았다. OTN 포럼의 전문가들은 일부 책을 읽고 프로그램의 성능을 향상 시키라고 조언했습니다. 아무도 나를 개선하는 데 도움이 될 수 있습니까? 고맙습니다.

코드 : OTN에서

또한
import org.apache.commons.io.FileUtils; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.FileReader; 
import java.io.IOException; 
import java.io.LineNumberReader; 
import java.io.PrintStream; 
import java.util.List; 

public class ReadFileToList { 

public static void main(String[] args) throws FileNotFoundException 
{ 


File file_out = new File ("D:\\Docs\\test_out.txt"); 
FileOutputStream fos = new FileOutputStream(file_out); 
PrintStream ps = new PrintStream (fos); 
System.setOut (ps); 

// Create a file object 
File file = new File("D:\\Docs\\test_in.txt"); 


FileReader fr = null; 
LineNumberReader lnr = null; 


try { 
// Here we read a file, sample.txt, using FileUtils 
// class of commons-io. Using FileUtils.readLines() 
// we can read file content line by line and return 
// the result as a List of string. 

List<String> contents = FileUtils.readLines(file); 
// 
// Iterate the result to print each line of the file. 


fr = new FileReader(file); 
lnr = new LineNumberReader(fr); 

for (String line : contents) 
{ 
String begin_line = line.substring(0, 38); // return 38 chars from the string 
String begin_line_without_null = begin_line.replace("\u0000", " "); 
String begin_line_without_null_spaces = begin_line_without_null.replaceAll(" +", " "); 

int stringlenght = line.length(); 
line = lnr.readLine(); 
int line_num = lnr.getLineNumber(); 

String status; 

// some correct length for if 
int c_u_length_f = 12; 
int c_ea_length_f = 13; 
int c_a_length_f = 2130; 
int c_u_length_e = 3430; 
int c_ea_length_e = 1331; 
int c_a_length_e = 442; 
int h_ext = 6; 
int t_ext = 6; 


if (stringlenght == c_u_length_f || 
stringlenght == c_ea_length_f || 
stringlenght == c_a_length_f || 
stringlenght == c_u_length_e || 
stringlenght == c_ea_length_e || 
stringlenght == c_a_length_e || 
stringlenght == h_ext || 
stringlenght == t_ext) 
status = "ok"; 
else status = "fail"; 



System.out.println(+ line_num + stringlenght + status + begin_line_without_null_spaces); 


} 
} catch (IOException e) { 
e.printStackTrace(); 
} 
} 
} 

전문가들은이 programm에 입력을 열고 두 번 읽는 말했다. "for 문"에서 실수가있을 수 있습니까? 그러나 나는 그것을 발견 할 수 없다. 감사합니다.

+0

한 번에 전체 파일을 읽지 않으시겠습니까? –

+1

코드 'line = lnr.readLine;' 두 번째 줄을 읽는 곳입니다. 이미 'content'에서 읽은 행을 foreach 루프에 넣었습니다. – Justin

+0

큰 파일 인 경우 파일을 섹션으로 분할합니다. OutOfMemoryError가 발생하면로드하는 파일이 너무 큽니다. – John

답변

1

루프 내부에서 변수를 선언하고 파일을 두 번 읽는 것을 포함하여 많은 uneeded 작업을 수행합니다. 성능에는 좋지 않습니다. 줄 번호 판독기를 사용하여 줄 번호와 텍스트를 가져 와서 줄 변수 (루프 외부에서 선언 된)를 다시 사용할 수 있습니다. 다음은 필요한 것을 수행하는 단축 버전입니다. 첫 번째 몇 가지 테스트 만 포함 했으므로 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(); 
     } 
    } 
} 

콜이 자바 TESTFILE의 D와 같은 : \ 문서 \ test_in.txt D : \ 문서 \의 test_in.txt 또는 인수가 [0]에 args [1] 파일 이름은 하드 코딩하려는 경우 교체 그들.

+0

Karakuricoder, 아주 아주 많이 !!! – May12

+0

내 (Karakuricoder) 코드의 인터페이스 양식을 만드는 데 읽을만한 것을 추천 해 주시겠습니까? – May12

+0

안녕하세요. May12, 감사합니다. 귀하의 질문을 이해할 수 있을지 모르겠다 - 사용자 인터페이스 또는 Java 클래스 인터페이스를 만들고 싶습니까? 사용자 인터페이스 인 경우 Google을 사용하고 "java swing tutorial"을 입력하고 Oracle/Sun에서 자습서 중 하나를 선택하십시오. – karakuricoder

관련 문제