1

이 질문은 일반적인 내용 일 수 있지만 여기에서 주요한 의미를 이해하려고합니다.ByteArrayInputStream을 사용하여 "올바른"표시/재설정 동작을 수행 할 때의 위험/보장

BCEL 라이브러리를 사용하여 일부 바이트 코드 엔지니어링을 시도하고 있으며 워크 플로의 일부에서 같은 바이트 코드 파일을 여러 번 (처음부터) 읽어야합니다. 흐름은 다음과 같습니다

// 1. Get Input Stream 

// 2. Do some work 

// 3. Finish 

// 4. Do some other work. 

4 단계에서 마크를 재설정하거나 처음부터 스트림을 가져와야합니다. 나는 다음과 같은 선택을 안다.

1) BufferedInputStream 사용하여 스트림 랩 - 얻기의 기회를 IOException이

2)는이 InputStream를 사용해서 랩 "잘못된 표시로 재설정"- 일부 온라인 조사가 오류의 제안하지만 항상 심지어 작동?

3) 스트림에서 다시 읽어야 할 경우 getInputStream()으로 간단히 전화하십시오.

나를 위해 어떤 옵션이 더 좋을지 이해하려고합니다. 마지막으로 mark이 호출 된 곳이 없으므로 BufferedInputStream을 사용하지 않으므로 더 높은 표시 위치에 대해 reset을 호출하면 IOException이 발생합니다. 나를 위해 최소한의 코드 변경이 필요하기 때문에 ByteArrayInputStream을 사용하는 것이 더 좋을 것입니다.하지만 누구나 옵션 # 2 또는 옵션 # 3이 더 좋을지 제안 할 수 있습니까?

mark() 및 reset()에 대한 구현이 JDK의 ByteArrayInputStreamBufferedInputStream에서 서로 다릅니다.

감사

+0

기본적으로'.class' 파일이되는'File'을 읽고 있습니까? 한 번 읽지 않고 바이트 배열에 저장하는 것이 어떻습니까? – Eugene

+0

@Eugene 네, 저는 이미 그렇게하고 있습니다 - 작동하지만 저는 신자 또는 "전문가 의견"이며 내가 고려하지 않은 걸음이 있기를 바라고 있습니다. 뭐 알아? – ha9u63ar

+0

전체 입력 스트림을 읽지 않으려는 경우 mark 및 reset을 사용하는 것이 중요하다는 것을 알고 있습니다. 또는 다음에 무엇을해야하는지 알기 위해 다음의 몇 바이트를 읽으려고합니다. 그렇지 않으면 배열로 읽는 것이 가장 간단합니다 (그리고 가장 명확합니다) – Eugene

답변

3

mark/reset의 문제는 이러한 호출 사이에 읽고있는 데이터의 최대 양을 사전에 알고 있다고뿐만 아니라, 당신은 또한 코드가 당신의 뜻에 위임하고 있는지 알고있다 내부적으로이 기능을 사용하면 마크를 쓸모 없게 만들 수 있습니다. mark/reset을 사용하는 코드는 발신자의 이전 표시를 기억하고 복원하는 것이 불가능합니다.

총 파일 크기를 최대 readlimit으로 지정하여 최대 문제를 해결하는 것이 가능하지만 명시 적으로 사용하지 않는 것으로 명시되지 않은 임의의 라이브러리 함수에 InputStream을 전달할 때 작업 표시에 의존해서는 안됩니다 내부적으로는 mark/reset 기능입니다.

또한 readlimit이 전체 파일 크기와 일치하면 ByteArrayInputStream은 전체 파일을 포함하는 배열을 래핑하는 것보다 효율적입니다. 두 파일 모두 동일한 크기의 버퍼를 유지하므로 결국 더 효율적입니다.


가장 좋은 해결책은 전체 클래스 파일을 한 번 배열로 읽은 다음 해당 배열을 직접 사용하는 것입니다. (ASM의 ClassReaderInputStream 대신 바이트 배열을 사용하는 것을 지원합니다). 당신이 그것을 주장 라이브러리 함수에 InputStream를 공급해야하는 경우

, BCEL처럼, 다음 필요할 때 ByteArrayInputStream에 바이트 배열을 포장하지만, 클래스를 다시 구문 분석에 당신이 새로운ByteArrayInputStream마다 생성 파일.새로운 ByteArrayInputStream을 구성하는 것은 가벼운 래퍼이며 신뢰할 수 있기 때문에 비용이 들지 않습니다. 어떤 식 으로든 오래된 입력 스트림의 상태에 의존하지 않으므로. 같은 배열을 동시에 여러 개의 ByteArrayInputStream 인스턴스가 읽도록 할 수도 있습니다.

getInputStream()을 다시 호출하면 전체 내용을 버퍼링하는 매우 큰 파일을 처리해야하는 경우 옵션이되지만 클래스 파일에는 해당되지 않습니다.

+0

저는 실제로 파일 내용 (byte [])을'ByteArrayInputStream'에 랩핑하고이를 API의 최소한의 변경으로 전달하고 있습니다 - 이것은 저에게 효과적입니다. 당신 자신과 @Eugene 모두 당신의 의견에 이것을 가지고있는 것처럼 보입니다. 나는 이것으로 행복하다. – ha9u63ar