2013-03-04 9 views
3

5 초마다 (예를 들어) 서버는 파일이 특정 디렉토리에 추가되었는지 확인합니다. '예'라고 답한 경우 해당 내용을 읽고 처리합니다. 관련 파일은 상당히 클 수 있습니다 (예 : 100+ Mo). 따라서 해당 디렉토리로 파일을 복사/업로드하는 것은 상당히 길 수 있습니다.파일 내용이 복사/업로드 완료되지 않은 상태에서 읽기

서버가 복사/업로드가 완료되지 않은 파일에 액세스하려고하면 어떻게됩니까? JAVA는 이러한 동시 액세스를 어떻게 관리합니까? 그것은 서버의 OS에 의존 하는가?


은 내 로컬 컴퓨터에 원격 서버에서 ~ 1,300,000 줄 TXT 파일 (즉, 약 200 모) ​​복사 시도했다 : 그것은 약 5 초 정도 걸립니다. 나는 다음과 같은 예외가 얻을

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

    String local = "C:\\large.txt"; 

    BufferedReader reader = new BufferedReader(new FileReader(local)); 
    int lines = 0; 
    while (reader.readLine() != null) 
     lines++; 
    reader.close(); 

    System.out.println(lines + " lines"); 

} 

:이 경과하는 동안, 나는 다음과 같은 자바 클래스 실행

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:2882) 
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100) 
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:515) 
    at java.lang.StringBuffer.append(StringBuffer.java:306) 
    at java.io.BufferedReader.readLine(BufferedReader.java:345) 
    at java.io.BufferedReader.readLine(BufferedReader.java:362) 
    at main.Main.main(Main.java:15) 

파일이 복사 완료되면 클래스를 실행, 내가 예상 출력을 얻을를 (즉, 1229761 lines), 예외는 파일의 크기 때문이 아닙니다 (처음에 생각할 수있는 것처럼). JAVA가 배경으로 수행하고있는 것, 이건 예외입니까?

+0

정품 OOME이 아닌지 확인하기 위해 많은 Xmx로 실행 해 보았습니까? – assylias

+0

제 생각 엔 readLine()은 어떤 이유로 든 개행 문자를 찾지 못합니다 (새 줄 문자가 어떤 이유로 든 다르고, 다른 O.S. 또는 일부 인코딩 문제가 있기 때문일 수 있습니다). 한 번에 매우 큰 행을 읽는 것 같습니다. – ddmps

+0

@assylias 최대 1Gb의 Java 힙 크기 (예 :'-Xmx1024m')로 시도했지만 예외가 여전히 발생합니다. – sp00m

답변

1

JAVA는 이러한 동시 액세스를 어떻게 관리합니까? 그것은 서버의 OS에 의존 하는가?

특정 OS에 따라 다릅니다. 단일 JVM AsynchronousFileChannel (new in 1.7) 클래스에서 사본과 서버를 실행하면 큰 도움이 될 수 있습니다. 그러나 클라이언트와 서버가 다른 JVM (또는 다른 시스템에서 시작된 경우)으로 표현되는 경우 플랫폼과 관련이 있습니다.

되는 FileChannel와 같이 JavaDoc for AsynchronousFileChannel:

에서,이 클래스의 인스턴스가 제공하는 파일의 뷰는 동일한 프로그램의 다른 인스턴스에 의해 제공된 같은 파일의 뷰와 일치되도록 보장된다 . 그러나이 클래스의 인스턴스 이 제공하는보기는 기본 운영 체제에서 수행 한 캐싱과 네트워크 파일 시스템 프로토콜에 의해 유발 된 지연으로 인해 동시에 실행되는 다른 프로그램에서 볼 수있는보기와 일치 할 수도 있고 아닐 수도 있습니다. 이는 다른 프로그램이 작성된 언어와 동일한 기계 또는 다른 기계에서 실행 중인지 여부와 상관없이 사실입니다. 이러한 불일치의 정확한 특성은 시스템에 따라 다르므로 지정되지 않습니다.

1

왜 버퍼링 된 리더를 사용하여 회선을 계산합니까?

javadoc에서 : 문자, 배열 및 행을 효율적으로 읽을 수 있도록 문자를 버퍼링하여 문자 입력 스트림의 텍스트를 읽습니다.

이것은 "버퍼링"됨을 의미합니다. 그 전체 파일을 메모리에 저장하면 스택 덤프가 발생합니다. FileReader를 사용해보십시오.

+0

질문은 줄을 읽지 않고 그런 파일에 액세스하는 것입니다. 방금 내 문제를 설명하기위한 모범을 보였습니다. – sp00m

+1

내 대답은 실제로 여전히 정확합니다. 왜 Oome을 얻었는지 궁금해했습니다. 거대한 파일을 메모리에 넣으려고하기 때문입니다. 이것은 두 가지 선택을 남겨 둡니다. 1. 메모리에 넣지 마십시오 (위에서 제안한대로). 2. 다른 사람이 제안한대로 -Xmx 플래그를 통해 메모리 양을 늘립니다. – JoeG

관련 문제