2013-09-28 3 views
3

를위한 JavaDoc를 작성되었습니다Java에서 버퍼링 된 스트림을 버퍼링 한 결과는 무엇입니까?

/** 
* ...Buffers the input stream so do not pass in a BufferedInputStream ... 
*/ 
public static void meth(InputStream is) throws IOException { 
    BufferedInputStream bis = new BufferedInputStream(is, 
      INPUT_STREAM_BUFFER_SIZE); 
    // rest omitted 
} 

하지만 정말에 버퍼링 된 입력 스트림을 전달하는 문제? 그래서이 :

InputStream is = new BufferedInputStream(new FileInputStream("C:/file"), SIZE); 
meth(is); 

bisis 버퍼 것 - 또는 자바 is 이미 버퍼링 bis = is 설정되어 있는지 감지 할 것인가? 그렇다면 다른 버퍼 크기가 달라질 수 있습니까? 그렇지 않다면, 왜 안 되니?
NB : 입력 스트림에 대해 이야기하고 있지만 실제로 출력 스트림에도 문제가 있습니다.

답변

4

하지만 실제로 버퍼링 된 입력 스트림을 전달하는 것이 문제가됩니까?

아니요. 이를 수행하는 데 약간의 오버 헤드가있을 수 있지만, 입력을 읽는 전체 비용과 비교하면 무시할 만합니다.

BufferedInputStream 코드 (예 : read1 메소드)를 보면 버퍼링 된 스트림이 스택 될 때 블록 읽기가 효율적으로 구현된다는 것을 알 수 있습니다.

[예제 코드 :] Java가 이미 버퍼되어 있는지 감지하고 bis = is을 설정 했습니까?

번호

없는 경우, 왜?

Java (언어, 컴파일러)는 일반적으로 Java 라이브러리 클래스의 의미를 이해하지 못하기 때문에. 그리고이 경우, 그러한 최적화의 이점은 무시할 수 있기 때문에 구현할 가치가 없습니다.

물론,이 종류의 일을 명시 적으로 수행 할 수있는 meth 메서드를 자유롭게 작성할 수 있습니다.하지만 약간의 차이는있을 것이라고 예측합니다.


꽤 왜 READ1 그들이 요구 된 길이가 일까 buf.length보다 작은 (또는 경우에만 입력 버퍼에 복사 "방해"하지 않는 입력에 표시된 위치가있는 경우 스트림)

난 당신이) read1에서 (이 코드를 참조한다고 가정 :

if (len >= getBufIfOpen().length && markpos < 0) { 
     return getInIfOpen().read(b, off, len); 
    } 

은 첫 번째 부분은 경우 사용자가 일 미만 요구하고 있음을 말하고있다 e 스트림의 구성된 버퍼 크기 때문에 버퍼링을 단락시키고 싶지는 않습니다. (그렇지 않은 경우 요청한 길이가 작은 read(byte[], int, int)을 수행하면 문제가 발생할 수 있습니다.)

두 번째 부분은 표시/재설정이 구현되는 방식과 관련이 있습니다. 기본 스트림 (지원되거나 지원되지 않을 수도 있음)에서 mark/reset을 사용하는 대신 BufferedInputStream은 버퍼를 사용하여 구현합니다. 당신이보고있는 것은 그 논리의 일부입니다. (당신은 직접 세부 사항을 작업 할 수 있습니다. 소스 코드에서 주석을 읽습니다.)

+0

나는'read1'에서 요청 된 길이가 buf.length보다 적거나 (입력 스트림에 표시된 위치가있는 경우) 입력 버퍼에 복사하는 것이 왜 "귀찮은"지 알 수 없다. 가장 통찰력이있어서 받아 들일 것입니다. –

0

대답은 없습니다. 자바가 이중 버퍼링을 감지하지 못합니다.

이 문제를 피하는 것은 사용자의 책임입니다. BufferedInputStream은 생성자로 전달한 InputStream이 버퍼링되었는지 여부를 알 수 없습니다.

public BufferedInputStream(InputStream in, int size) { 
    super(in); 
    if (size <= 0) { 
     throw new IllegalArgumentException("Buffer size <= 0"); 
    } 
    buf = new byte[size]; 
} 

편집 가 스트림 버퍼 두 배로 문제가 코멘트에서

: 여기

BufferedInputStream 생성자의 소스 코드?

짧은 대답은 입니다.

버퍼링의 개념은 데이터를 메모리로 스풀링하고 (일반적으로 매우 느린 IO로) 청크로 작성하도록 속도를 높이는 것입니다. 버퍼를 이중 버퍼링하면 데이터를 메모리에 스풀링 한 다음 해당 데이터 을 다른 곳의 메모리으로 플러시합니다. 이것은 확실히 속도면에서 비용이 있습니다 ...

+1

왜 isof는 BufferedInputStream입니까? 소스에 대한 링크를 제공 할 수 있습니까? –

+0

하지만'DataInputStream'은 어떨까요? 'ObjectInputStream'? 'MyRandomBufferedStream'? 스트림이 버퍼링되는지 여부를 감지하는 방법은 없습니다. –

+0

일종의 생각 이었지만 해킹이있었습니다. 질문이 남아 있습니다. 스트림을 두 번 버퍼링하는 것이 문제입니까? 이 조항을 java 문서에 추가해야합니까? ;) –

1

스트림을 두 번 버퍼링하면 더 많은 메모리를 사용하게되고 한 번만 수행하면 속도가 느려지지만 여전히 작동합니다.

사용자가 스스로 그렇게 할 필요가 없다는 것을 알 수 있도록 스트림이 버퍼링한다는 것을 문서로 기록하는 것이 좋습니다.

일반적으로 이런 종류의 오용을 적극적으로 방지하는 것이 가장 바람직합니다.

+0

소스 코드를 확인하십시오. BufferedInputStream은 전체 버퍼로드가 복사되는 경우 '그리스 된 경로'를 사용하여 스택하는 경우 손상을 최소화합니다. – EJP

+0

@EJP; 그것이 그렇지 않았다면 그것은 특이 할 것이다. 그러나 비용은 0이 아니므로, 내가 말한 것을 변경한다고 생각하지 않습니다. –

+0

비용이 0이 아닌 방법은 무엇입니까? 추가 메서드 호출은 실제 I/O와 비교하면 아무 것도 없습니다. – EJP