2015-02-07 2 views
0

죄송합니다. 큰 파일을 읽고 싶지만 오류가 발생하면 outOfMemoryError이 발생합니다. 응용 프로그램에서 메모리로 작업하는 방법을 이해하지 못합니다. 다음 코드는 작동하지 않습니다.큰 파일 오류 "outofmemoryerror"(java)

try { 

    StringBuilder fileData = new StringBuilder(1000); 
    BufferedReader reader = new BufferedReader(new FileReader(file)); 

    char[] buf = new char[8192]; 
    int bytesread = 0, 
     bytesBuffered = 0; 

    while((bytesread = reader.read(buf)) > -1) { 

     String readData = String.valueOf(buf, 0, bytesread); 
     bytesBuffered += bytesread; 

     fileData.append(readData); //this is error 

     if (bytesBuffered > 1024 * 1024) { 
      bytesBuffered = 0; 
     } 
    } 

    System.out.println(fileData.toString().toCharArray()); 
} finally { 

} 
+0

사용할 수있는 가장 높은 Java 버전은 무엇입니까? 이런 방식으로 파일을 읽는 것은 꽤 오래된 것입니다. 안드로이드 등으로 인해 Java 6을 사용해야합니다. 그렇지 않으면 Java 8의 Stream API를 사용해야합니다. – Bevor

+0

1.70_71을 사용합니다. readLine()이 아닌 큰 파일을 읽어야합니다. 파일 (5GB)에는 한 줄만 쓸 수 있기 때문에 – qazqwerty

답변

0

당신은 재 할당을 피하기 위해 큰 버퍼를 할당 사전이 필요합니다.

File file = ...; 
StringBuilder fileData = new StringBuilder(file.size()); 

그리고 큰 힙 크기 실행 :

java -Xmx2G 

==== 업데이트를

얼마 루프를 실행하는 데 너무 메모리를 필요로하지 않는 버퍼를 사용하여. 입력을 스트림처럼 취급하고 검색 문자열을 스트림과 일치시킵니다. 정말 간단한 상태 기계입니다. 여러 단어를 검색해야하는 경우이를 위해 TrieTree 구현 (지원 스트림)을 찾을 수 있습니다. 당신이 부족하기 때문에 당신이 볼로

// the match state model 
...xxxxxxabxxxxxaxxxxxabcdexxxx... 
     ab  a  abcd 

    File file = new File("path_to_your_file"); 
    String yourSearchWord = "abcd"; 
    int matchIndex = 0; 
    boolean matchPrefix = false; 
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) { 
     int chr; 
     while ((chr = reader.read()) != -1) { 
      if (matchPrefix == false) { 
       char searchChar = yourSearchWord.charAt(0); 
       if (chr == searchChar) { 
        matchPrefix = true; 
        matchIndex = 0; 
       } 
      } else { 
       char searchChar = yourSearchWord.charAt(++matchIndex); 
       if (chr == searchChar) { 
        if (matchIndex == yourSearchWord.length() - 1) { 
         // match!! 
         System.out.println("match: " + matchIndex); 
         matchPrefix = false; 
         matchIndex = 0; 
        } 
       } else { 
        matchPrefix = false; 
        matchIndex = 0; 
       } 
      } 
     } 
    } 
+0

답장을 보내 주셔서 감사합니다. 예를 들어 10GB 파일에서이 'StringBuilder fileData = new StringBuilder (file.size());'를 사용하면 괜찮습니다. ' – qazqwerty

+0

10GB 파일로 수행 할 작업을 설명 할 수 있습니까? 이 과정은 당신의 직업에 따라 다를 수 있습니다. – javamonk

+0

원하는 단어가 들어있는 문자열을 찾으려면 큰 파일 (5-10GB)이 필요합니다. 나는 그것을하는 법을 모른다. 어쩌면 너무 많은 성격 지향적이거나 여러 부분으로 된 다운로드 일 수도있다. 그 예를 찾아내는 것이 좋을 것입니다. – qazqwerty

0

시도해보십시오. 이 도움이 될 수 있습니다 -

try{ 
    BufferedReader reader = new BufferedReader(new FileReader(file)); 
    String txt = ""; 
    while((txt = reader.read()) != null){ 
     System.out.println(txt); 
    } 
}catch(Exception e){ 
    System.out.println("Error : "+e.getMessage()); 
} 
+0

답변 해 주셔서 감사합니다. 이 오류는'txt = reader)! = null', 해결되지 않은 컴파일 문제 : 형식 불일치 : BufferedReader에서 String으로 변환 할 수 없습니다. – qazqwerty

+0

@ qazqwerty 죄송합니다. 내 나쁜 ... 그것의'reader.read()'. 수정 된 코드를 참조하십시오 – khandelwaldeval

+0

@qazqwerty 또한 답을 받아들이는 것을 잊지 마십시오 – khandelwaldeval

0

당신은, 메모리와 같은 큰 파일을 보유하지 않아야합니다. 자바 7을 사용하기 때문에 파일을 스트림으로 수동으로 읽고 내용을 즉시 확인해야합니다. 그렇지 않으면 Java 8의 스트림 API를 사용할 수 있습니다. 이는 단지 예일뿐입니다. 그것은 작동하지만, 명심, 검색된 단어의 위치로 인해 문제를 인코딩에 따라 다를 수 있다는 것을, 그래서 이것은 더 생산 코드입니다 :

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 

public class FileReader 
{ 
    private static String wordToFind = "SEARCHED_WORD"; 
    private static File file = new File("YOUR_FILE"); 
    private static int currentMatchingPosition; 
    private static int foundAtPosition = -1; 
    private static int charsRead; 

    public static void main(String[] args) throws IOException 
    { 
     try (FileInputStream fis = new FileInputStream(file)) 
     { 
      System.out.println("Total size to read (in bytes) : " + fis.available()); 

      int c; 
      while ((c = fis.read()) != -1) 
      { 
       charsRead++; 
       checkContent(c); 
      } 

      if (foundAtPosition > -1) 
      { 
       System.out.println("Found word at position: " + (foundAtPosition - wordToFind.length())); 
      } 
      else 
      { 
       System.out.println("Didnt't find the word!"); 
      } 

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

    private static void checkContent(int c) 
    { 
     if (currentMatchingPosition >= wordToFind.length()) 
     { 
      //already found.... 
      return; 
     } 

     if (wordToFind.charAt(currentMatchingPosition) == (char)c) 
     { 
      foundAtPosition = charsRead; 
      currentMatchingPosition++; 
     } 
     else 
     { 
      currentMatchingPosition = 0; 
      foundAtPosition = -1; 
     } 
    } 
}