2011-12-14 2 views
3

wiki.txt 파일이 있고 그 크기는 50MB입니다.자바에서 텍스트 파일을 메모리에로드하십시오.

  1. 올바른 것입니다, 나는 파일에 여러 가지 일을 할 필요가 있고 그래서 나는 성능면에서 가장 좋은 방법은 메모리에 파일을로드하는 것입니다 생각?

    File file = new File("wiki.txt"); 
    FileInputStream fileInputStream = new FileInputStream(file); 
    FileChannel fileChannel = fileInputStream.getChannel(); 
    MappedByteBuffer mapByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 
    System.out.println((char)mapByteBuffer.get()); 
    

가이 코드에 오류가 발생합니다 : :

  • 내가 작성한 코드입니다 mapByteBuffer.get(). get() 함수에 몇 가지 옵션을 시도했지만 모두 오류가 발생하여 e.getMessage()에서 오류가 발생하지 않았습니다. 그냥 null이 있습니다.

    내 텍스트 파일에 영어 단어가 포함되어 있으며이 텍스트 파일에 표현 된 단어가 검색되면 검색이 필요하다는 점에 유의해야합니다.

    감사합니다.

  • +2

    어떤 오류가 발생합니까? – bvd

    +0

    오류 메시지를 게시하십시오. 또한 텍스트 파일에서 몇 개의 샘플 라인을 보는 것이 도움이 될 것입니다. 그러면 우리는 그 파일을 읽고 저장하는 효율적인 방법을 제안 할 수 있습니다. –

    답변

    3

    MemoryMappedFile을 사용하여 파일을 메모리에서로드하는 대신 디스크에서 직접 읽는 것이 좋습니다.

    RandomAccessFile file = new RandomAccessFile("wiki.txt", "r"); 
    FileChannel channel = file.getChannel(); 
    MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024*50); 
    

    그런 다음 평소대로 버퍼를 읽을 수 있습니다.

    +0

    하지만 여기에 나와 제안 해주세요. 50K를 읽을 때마다이 작은 버퍼에서 검색을 수행합니까? 두 번째, 세 번째 ... 시간이 지나면 더 많은 검색을해야 할 것입니다. 파일의 마지막 (50MB)으로 돌아올 때까지 50K로드를 모두 수행 할 것입니까? –

    1

    BufferedReader를 사용하는 것이 좋습니다. 그것은 훨씬 더 빠르며 비교적 적은 리소스를 필요로합니다. 라인의 먼저 읽기 번호 :

    InputStream is = new BufferedInputStream(new FileInputStream(filename)); 
    byte[] chars = new byte[1024]; 
    int numberOfChars = 0; 
    while ((numberOfChars = is.read(chars)) != -1) 
    { 
        for (int i = 0; i < numberOfChars; ++i) 
        { 
         if (chars[i] == '\n' && numberOfChars - i != 1) 
         { 
          ++count; 
         }   
        } 
    } 
    count++ 
    return count; // number of lines 
    

    그런 다음 줄을 읽기 : 당신도 당신이 필요로 검색 할 수있는이 문자열에서

    BufferedReader in = new BufferedReader(new FileReader(fileName)); 
    for (int i = 0; i < endLine; i++) 
    { 
        String oneLine = in.readLine(); 
    } 
    

    . 포인트

    +0

    하지만 몇 가지 다른 표현을 다시 검색해야합니다. 전체 파일을 다시 볼 때마다 정말 좋습니다. –

    +0

    좋은 생각이 아닙니다. 내 문자열이 50MB 파일의 끝에 있으면 긴 시간이 걸립니다. –

    2

    내 답변 (1) :

    그것은 당신이 파일에 수행 할 작업에 따라 달라집니다. 프로세싱이 되감기 작업 (뒤에서/전에 읽은 것을보고)을 포함하지 않는다면, 스트림으로 읽고 그것을 한 번에 처리하는 것이 가장 좋습니다 (모든 것을 메모리로로드하는 대신).

    파일 전체에서 임의 액세스가 필요한 경우에도 파일 크기가 더 큰 크기로 변경되면 솔루션의 확장이 제대로 이루어지지 않을 수 있으므로 블록 파일 작업을 수행하는 것이 좋습니다. Java 1.4 이상을 사용중인 경우 RandomAccessFile 랜덤 액세스의 경우 운영 체제는 일반적으로 파일 버퍼 캐싱을 처리하므로 사용자가 직접 처리 할 필요가 없습니다.

    +0

    나는 표현식 (몇 단어를 포함 할 수있는 문자열)을 얻었고 표현식이 텍스트 파일에 있다면 대답을 돌려줘야합니다. 그리고이 작업을 다른 표현식으로 여러 번 반복해야하지만 같은 텍스트 파일에서 반복해야합니다. –

    +0

    이제 문자열 검색 및 문자열 일치와 같은 요구 사항이 나에게 들립니다. 전처리를 할 경우 반복 할 필요가 없습니다. knuth-Morris-Pratt (http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm)와 같은 알고리즘을 검색하는 문자열을 살펴 보도록 제안합니다. –

    2

    메시지뿐만 아니라 전체 오류를 읽는 것이 중요합니다. 종종 실제 정보는 예외와 관련된 텍스트가 아닌 예외 이름에 있습니다.

    첫 번째 바이트가 없으므로 파일이 비어 있으면 오류가 발생합니다.

    참고 : 사용중인 접근 방식은 ASCII 7 비트 문자로 가정합니다. 사용할 수있는 ISO-8859-1 문자를 사용하려는 경우 (char) (byteBuffer.get() & 0xFF)

    그러나 계획 문자가있는 경우 문자열을 사용하면 훨씬 간단하고 사용 속도는 느려집니다. 예 : 50MB 파일을 1 초 안에 텍스트로 읽을 수 있습니다.너무 길면 메모리 매핑 된 파일 만 사용합니다.

    관련 문제