Program Club

Java에서 InputStream.available ()은 무엇을합니까?

proclub 2020. 12. 31. 22:17
반응형

Java에서 InputStream.available ()은 무엇을합니까?


JavaInputStream.available() 에서 무엇을 합니까? 문서를 읽었지만 여전히 이해할 수 없습니다.

문서 내용 :

이 입력 스트림에 대한 메서드의 다음 호출자가 차단하지 않고이 입력 스트림에서 읽거나 건너 뛸 수있는 바이트 수를 반환합니다. 다음 호출자는 동일한 스레드 또는 다른 스레드 일 수 있습니다.

InputStream 클래스에 사용할 수있는 메서드는 항상 0을 반환합니다.

차단 이란 무엇을 의미 합니까? 동기화 된 통화를 의미합니까?

그리고 무엇보다도이 available()방법 의 목적은 무엇 입니까?


차단은 여기서 스레딩 또는 동기화와 관련이 없습니다. 대신 IO 차단과 관련 이 있습니다 (자세한 내용은 여기 참조 ). 읽기 요청을 발행하고 채널에 사용 가능한 것이없는 경우 데이터를 사용할 수있을 때까지 (또는 채널이 닫히고, 예외가 발생하는 등) 차단 호출이 대기 (또는 차단)됩니다.

그렇다면 왜 사용 available()합니까? 따라서 읽을 바이트 수를 결정하거나 차단할지 여부를 결정할 수 있습니다.

Java에는 비 차단 IO 기능도 있습니다. 자세한 내용은 여기 를 참조하십시오.


InputStreams에서 read()호출은 "차단"메서드 호출이라고합니다. 즉, 메서드 호출시 사용할 수있는 데이터가없는 경우 메서드는 데이터를 사용할 수있을 때까지 기다립니다.

available()메서드는 read()호출이 프로그램의 실행 흐름을 차단할 때까지 읽을 수있는 바이트 수를 알려줍니다 . 대부분의 입력 스트림에서 모든 호출 read()이 차단되므로 사용 가능한 기본적으로 0을 반환합니다.

그러나 일부 스트림 (예 : BufferedInputStream내부 버퍼가있는)에서는 일부 바이트를 읽고 메모리에 보관하므로 프로그램 흐름을 차단하지 않고 읽을 수 있습니다. 이 경우 available()메서드는 버퍼에 보관되는 바이트 수를 알려줍니다.


실용적인 용도 중 하나는 available()합리적인 버퍼 길이를 선택하는 데 사용하는 것입니다.

static final int LEN = 4096;

long copy(InputStream in, OutputStream out) throws IOException {
    int count = 0L;
    int avl = in.available();
    if (avl == 0) {
        // 0 returned without IOException? possibly mean eof?
        return 0L;
    }
    //byte[] buf = new byte[avl == 0 ? LEN : Math.min(avl, LEN)];
    byte[] buf = new byte[Math.min(avl, LEN)];
    for (int len; (len = in.read(buf)) != -1; count+= len) {
        out.write(buf, 0, len);
    }
    return count;
}

문서에 따르면

반환 값 : 차단하지 않고 입력 스트림 0의 끝에 도달했을 때이 입력 스트림에서 읽거나 건너 뛸 수있는 바이트 수의 추정치 .

이 메소드의 서브 클래스 구현은 메소드 를 호출하여이 입력 스트림이 닫혔다 면를 던지도록 선택할 수 있습니다IOExceptionclose() .

최신 정보

나는 이미 아이디어가 권장되지 않는다는 것을 알고 있습니다. JDK 문서가 경고하기 전에도 그 위험을 알고 있습니다. (한때 available몇 GB 크기의 버퍼를 할당하려고 시도했습니다 FileInputStream.)

JDK8 / InputStream # available

이 메서드의 반환 값을 사용하여이 스트림의 모든 데이터를 보유 할 버퍼를 할당하는 것은 올바르지 않습니다.

JDK5 / InputStream # availabe

그러나 프로그래밍에서는 never또는 always wrong코드 가 없어야 합니다. 그게 제가 믿고있는 것입니다.


소프트웨어를 아주 나쁘게 작성하고 운영 체제를 작성하는지 고려하십시오.

이 운영 체제는 무엇보다도 키보드 입력을받습니다.

따라서 OS에 키보드 입력을 요청하지만 키를 누르지 않고 버퍼에 없습니다. 그러면 전체 OS가 키보드 입력을받을 때까지 HANG DEAD가됩니다.

이것을 '미리보기'와 대조하여 전화를 걸기 전에 KB에 문자가 있는지 묻습니다. 아니오라고 대답하면 OS가 다른 작업을 수행합니다.

그것이 당신이 관심을 가져야하는 이유입니다. 이제 다른 모든 잠재적 인 차단 작업을 곱하면 '미리보기'가 중요한 이유를 알 수 있습니다.

OUTPUT에도 적용되기 때문입니다. 디스크 드라이브 인터페이스에 대한 메모리는 처리 할 수있는 것보다 더 빨리 디스크 드라이브에 데이터를 넘길 수 있습니다. 드라이브 버퍼가 데이터로 가득 차 있다는 것을 모르는 경우 버퍼가 더 많은 데이터를 받아 들일 수있을 때까지 작업이 차단됩니다.

이것은 또한 '유용한 용도가 거의 없다'는 말도 안되는 것을 강조합니다.

참조 URL : https://stackoverflow.com/questions/3695372/what-does-inputstream-available-do-in-java

반응형