2012-03-09 1 views
2

Java 프로그램에서 stdin을 읽으려고합니다.readline()이 Java에서 null을 반환합니다.

6 
9 
1 

이클립스 내장 콘솔을 통해 입력을 제공하면 모든 것이 잘 진행됩니다. 그러나 Windows 명령 줄 프로그램의 인쇄 사용하는 경우 :

Received '6'. 
Received 'null'. 
Invalid input. Terminating. (This line is written by another function that does an Integer.parseint()). 

내 코드는 다음과 같습니다

static String readLineFromStdIn(){ 
try{ 
     java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); 
     String input = new String(); 
     input = stdin.readLine(); 
     System.out.println("Received '" + input + "'"); 
     return(input); 
    }catch (java.io.IOException e) { 
     System.out.println(e); 
    } 
    return "This should not have happened"; 
} 

모든 단서를?

+0

Eclipse 콘솔에서 입력을 입력하고 모든 숫자 뒤에 enter를 입력합니다.Windows에서는 "java -jar program.jar user1259401

답변

8

null을 얻으면 관련 Reader 개체가 EOF (파일 끝)에 도달했거나 다른 표준 입력을 얻을 수 없다는 것을 나타냅니다. 이제 코드로 명백한 문제는 다음과 같습니다

  1. readLineFromStdIn()에 각 메서드 호출이 새로운BufferedReader을 만듭니다.
  2. BufferedReaderSystem.in
  3. 에서 같은 공유 입력 서로 "경쟁"합니다 그리고이 BufferedReader 오브젝트의 누구도 제대로 readLineFromStdIn() 호출 할 때마다, 그래서 당신의 프로그램 누출 I/O 자원을 폐쇄하지 않습니다 같은.

용액을 는 단일readLineFromStdIn() 각 호출을위한 공유 오브젝트 BufferedReader 사용하는 것이다.

+0

그 트릭을 했어! 고마워. – user1259401

+0

'stdin'을 열 때마다, 기술적으로 파일 스트림을 열고 있다는 것을 의미하며, Java가 가질 수있는 열려있는 파일 연결 수를 초과하는 것은 결코 닫히지 않습니다. –

+0

@ user268396이 'BufferedReader'가 닫히면 System.in도 닫히고 바람직하지 않을 수 있습니다. 데코레이터 스트림을 닫지 않고 GC화할 수있는 드문 경우 일 수 있습니다. – Dev

2

이 질문에 대한 새로운 대답은 아니지만 원본 코드가 원래대로 작동 한 이유에 대한 의견에 혼란을 피하고자합니다 (ST에 처음 입했기 때문에 의견을 말할 수 없습니다. 평판 포인트).

null 결과는 가비지 수집과 관련이 없습니다.

BufferedReader r1 = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println(r1.readLine()); 
BufferedReader r2 = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println(r2.readLine()); 

그것은 모두 아래로 "버퍼"BufferedReader에 무엇을 의미하는지에 제공 : 다음 프로그램은 정확히 모두 독자가 여전히 살아 비록 같은 운명 접근 객체를 겪고있다. 내부 버퍼링을 포함하는 Reader입니다. 내부 버퍼링은 일반적으로 기본 스트림에서의 작업 효율성을 크게 향상시킵니다. 각 시간마다 전체 버퍼의 가치를 읽으려고 시도하는 것보다는 여기에 몇 바이트가 들어가는 스트림을 죽 이도록 희미하게 만드는 것보다 더 좋습니다.

그러면 stdin에서 첫 번째 BufferedReader을 만들고 그 행을 읽으면 어떻게됩니까? 즉, BufferedReader은 스트림에서 buffer-full을 읽고, 줄의 끝을 감지하고, 첫 번째 줄을 반환하고, 다음 요청을 채우기 위해 나머지 버퍼에 멈 춥니 다. 그러면 기본 스트림이 첫 번째 줄의 끝을 벗어나 배치됩니다. 입력 내용이 작 으면 EOF에 쉽게 배치 할 수 있습니다.

그래서 이제는 동일한 스트림 (EOF에있는) 위에 두 번째 BufferedReader를 만들고 라인을 가져 오려고 시도합니다. 두 번째 BufferedReader는 기본 스트림에서 읽기를 시도하고 EOF를 감지하므로 readLinenull을 반환합니다.