2010-03-23 3 views
2

난 버퍼링 판독기에서 판독하는 다음 예를 가지고버퍼링 된 리더에서 어떻게 읽어야합니까?

while ((inputLine = input.readLine()) != null) { 
    System.out.println("I got a message from a client: " + inputLine); 
} 

일 (이 경우 input) 버퍼링 리더에 나타날 때마다 루프 println의 코드가 실행될 것이다. 내 경우에는 클라이언트 응용 프로그램이 소켓에 뭔가를 쓰면 서버 응용 프로그램의 루프에있는 코드가 실행됩니다.

하지만 어떻게 작동하는지 이해할 수 없습니다. inputLine = input.readLine()은 버퍼링 된 리더에 무언가가 나타날 때까지 기다렸다가 무언가가 나타나면 true을 반환하고 루프의 코드가 실행됩니다. 그러나 null이 반환 될 수 있습니다.

또 다른 질문이 있습니다. 위의 코드는 throws Exception이라는 메서드에서 가져온 것으로 Thread의 run 메서드에서이 코드를 사용합니다. 그리고 컴파일러가 run 전에 throws Exception을 넣으려고하면 컴파일러에서 불평합니다. 재정의 된 메서드가 예외를 throw하지 않습니다. throws exception이 없으면 나는 컴파일러로부터 또 다른 불평이있다 :보고되지 않는 예외. 그래서 내가 무엇을 할 수 있니?

+0

@Roman - 당신은 거래를 알고 있습니다. 서로 다른 질문에 넣어 다른 질문! –

+0

Stephen C, 추가 된 부분이 "버퍼 된 리더에서 어떻게 읽어야합니까?"의 일부라고 생각했습니다. 하지만 당신의 요점을 봅니다. 나는 추가 된 부분을 제거했다. – Roman

답변

5

다른 끝 소켓이 닫히면 판독기는 null 문자열을 반환해야합니다. 이것은 당신이 찾고있는 조건입니다. 예외를 처리하려면 try/catch 블록에서 읽기 루프를 래핑하십시오.

이 소켓은 Java의 소켓에서 읽고 쓰는 데 유용 할 수 있습니다.

0

input 판독기가 수신자 인 소켓에 연결되어 있습니다. 즉 수신 메시지를 계속 수신합니다.

두 번째 질문에 대해서는 try/catch 블록을 메서드 내에두고 예외를 catch하고 처리해야합니다. 다시 던지지 마라.

1

독자의 readLine()은 읽은 값이 있으면 문자열 값을 반환하고 아직 읽지 않은 값이 있으면 빈 문자열을 반환하고 연결을 닫으면 null을 반환합니다.

IO 기능으로 코드 블록 주위에 try/catch를 배치하고 오류를 적절하게 처리하는 것이 좋습니다.

0

그러나 어떻게 작동하는지 이해할 수 없습니다. 뭔가 버퍼 리더 나타나고이 나타납니다 뭔가가 true를 돌려주는 경우

아니,이 식의 값을 반환 할 때까지 .... 기다립니다 (inputLine = input.readLine())는 inputLine 자체 . inputLine은 null과 비교됩니다.

0

"EOF (파일 끝)"에 도달하면 null이 반환됩니다. 이것은 네트워크 소켓에서 읽는 것이므로 소켓 종료시 (서버 또는 클라이언트에 의해) 파일 끝이 생성되지만 실제로 EOF를보기 전에 예외가 발생할 가능성이 높습니다.

0

숙제가 아닌 경우 Apache Commons IOUtils을 참조하십시오.

당신의 BufferedReader를 생성하지 않는 가정, 단지의 InputStream에서 중지 : 식의 각 부분에서

String results = IOUtils.toString(inputStream); 
System.out.println(results); 
0
while ((inputLine = input.readLine()) != null) { 

봐 :

input.readLine() 

는 것이다 문자열을 반환 스트림의 마지막에 이르렀을 경우는 null, 또는 에러가 발생했을 경우는 Exception를 throw합니다.

inputLine = input.readLine() 

를 할당이 문자열은 할당 된 문자열이 null이

((inputLine = input.readLine()) != null) 

수표 (스트림의 끝) inputLine한다. 첫 번째 질문에 대한

3

:

그러나 그것이 어떻게 작동하는지 이해가되지 않습니다. inputLine = input.readLine()은 버퍼링 된 판독기에 무언가가 나타날 때까지 기다리고 무언가가 나타나면 true를 반환하고 루프의 코드가 실행됩니다. 하지만 null을 반환 할 수 있습니다.

BufferedReader.readLine() 성공시 true을 반환하지 않습니다. 읽은 행을 포함하는 String을 리턴합니다. 스트림의 끝에 도달하면 null을 반환합니다.

두 번째 질문 : 위의 코드는 예외를 throw하는 방법에서 찍은 내가 스레드의 실행 방법이 코드를 사용

. 그리고 예외를 던지려고 할 때 컴파일러는 불만을 토로합니다 : 오버라이드 된 메소드는 예외를 발생시키지 않습니다. throws 예외가 없으면 컴파일러로부터 또 다른 불평이 있습니다. unreported exception. 그래서 내가 무엇을 할 수 있니?

코드를 try/catch block으로 묶어야합니다. 잡힌 예외를 처리하지 않으려면 해당 부분을 비워 두십시오 (권장하지 않음).

try { 
    while ((inputLine = input.readLine()) != null) { 
     System.out.println("I got a message from a client: " + inputLine); 
    } 
} catch (Exception e) { 
    //handle exception 
} 
0

좋은 답변을 받았습니다. 그냥 예외를 잡아서 로컬로 처리하십시오. 이 코드를 다른 코드로 전달해야하지만 run() 메서드가 검사 예외를 허용하지 않기 때문에 예외를 RuntimeException에 래핑 할 수 있습니다. run 메서드가 Thread에서 직접 실행되는 경우 (아마도 Runnable이므로) 래핑 된 예외를 다시 throw하는 데주의해야합니다. 읽을 아무것도가없는 경우 readLine()의 결과에 관해서는

, 그것은 null를 반환합니다. 소켓의 경우 이것은 상대방이 소켓을 깨끗이 닫을 때 발생합니다 (OS가 다른 종류의 소켓 닫기 알림을 보내면 갑작스러운 종료 또는 불완전한 종료로 인해 일반적으로 코드에서 예외가 발생합니다).

java.io.BufferedReader에 소켓을 감싸고 있으므로주의해야합니다. 어떤 종류의 프로덕션 코드에서든 이것을 사용하는 것에 매우주의해야합니다.

위험한 점은 BufferedReader가 읽기 도중에 예외가 발생하지 않는다는 것입니다. 이는 코드가 운영 체제에서 정기적으로 예외를 자동 수신하도록 소켓에서 시간 제한을 활성화 한 경우 특히 문제가됩니다. 리더 내부의 버퍼가 채워지는 동안 타임 아웃 (또는 다른 예외)이 올 수 있습니다. 예외 후에 오브젝트를 재사용하려고하면 버퍼의 이전 내용을 무시합니다. 이전에 수신 된 패킷은 자동으로 손실되며 해당 바이트를 검색 할 수있는 방법이 없습니다.

소켓이 손실되었다는 것을 의미하지는 않는 다른 종류의 소켓 예외가 있습니다. 예를 들어 java.io.InterruptedIOException의 정의를 살펴보십시오. 여기에는 가장 최근의 I/O (읽기 또는 쓰기) 요청에서 성공적으로 전송 된 바이트 수를보고하는 공용 변수가 있습니다. 즉, IO 작업을 다시 실행하여 패킷의 나머지 바이트를 검색하거나 보낼 수 있습니다.

독자의 설계가 독자와 소켓을 즉시 닫는 것이면 그 방법은 올바르게 작동합니다.

소켓에서 직접 읽는 방법은 소켓 스트림을 직접 사용하거나 NIO (ByteBuffers 등)를 사용하거나 이러한 낮은 수준의 클래스에 대해 잘 추상화 된 잘 작성된 네트워크 라이브러리를 사용하는 것입니다 (여러 가지 오픈 소스를 사용할 수 있음).).

관련 문제