2017-11-17 24 views
0

응용 프로그램에서 최근에 발견 된 문제를 분석하려고 시도한 결과 FileInputStream에서 작동하려고했기 때문에 inputStream.reset() 메서드가 실패했습니다.Struts DiskFile.getInputStream()은 파일 크기가 변경 될 때 ByteArrayInputStream 및 FileArrayInputStream을 반환합니다.

아파치의 DiskFile.getInputStram() 인스턴스는 특정 파일 크기 임계 값을 기준으로 ByteArrayInputStream 인스턴스 (지원됨) 또는 FileInputStream (지원되지 않음) 인스턴스를 반환합니다.

나는이되는 InputStream을 얻을해야하는 코드는 다음과 같습니다

FormFile file = multipartForm.getFiles().get(0); // It's always one file 
InputStream is = file.getInputStream(); 

// Read the stream and did job 
// Now I want to reset it. 
// bad coding from my side because I didn't check markSupported 

is.reset(); 

// Got IO error immediately after this. But anything below 256KB is ok 

나는이 언급 확신/오라클 JDK의 문서 또는 아파치 사이트의 어딘가에 설명했다. 어떤 참고 문헌도 기억하지 못하는 것 같습니다. 이 행동이 타당한 지 아는 사람이 있습니까?

+0

그래서'DiskFile.getInputStram()가''InputStream'과 기본을 반환 그것의 구현은 파일의 크기에 따라'ByteArrayInputStream' 또는'FileInputStream'입니까? – Eugene

+0

예 - 테스트 결과가 올 바르면 Windows에서 256KB를 초과하는 항목은 FileInputStream 구현을 반환하지만 더 낮은 크기는 ByteArrayInputStream이됩니다. – ha9u63ar

+0

소스를 확인할 수 있습니까? 여기 https://svn.apache.org/repos/asf/struts/struts1/tags/STRUTS_1_2_1/src/share/org/apache/struts/upload/DiskFile.java를 찾고 있는데이 경우가 아닙니다. – Eugene

답변

2

Struts API에 익숙하지 않지만 특정 서브 클래스가 아닌 반환 유형이 InputStream 인 경우 리턴 된 스트림의 실제 유형에 대해서는 보장 할 수 없습니다.

일반적으로 지정되지 않은 InputStream 유형을 치료하는 선행 mark(readlimit) 전화를 가진 경우 reset()를 호출하는 경우에만 유효하기 때문에 바로 감기이다

InputStream inputStream = … 
int readlimit = … 

if(!inputStream.markSupported()) { 
    inputStream = new BufferedInputStream(inputStream, readlimit); 
} 

inputStream.mark(readlimit); 
// read some date, not more than readlimit 
inputStream.reset(); 
+0

BufferedInputStream은 항상 w 오크.Invalid Mark에 재설정이 발생했기 때문에 IOException이 발생하는 인스턴스를 보았습니다. content 바이트가 사용 가능하면 ByteArrayInputStream을 사용하는 것이 안전합니다. – ha9u63ar

+2

그러면 네 잘못이야. 지정한'readLimit' 바이트 수 이상을 읽지 않아야합니다. 그렇지 않으면 마크가 유효하지 않고'reset()'이 더 이상 지원되지 않습니다. 'readLimit'을 체크하지 않는'ByteArrayInputStream'으로 잘못된 동작을 피할 수 있습니다 만,'reset()'을 호출하기 전에 지정된 것보다 많은 바이트를 읽는 것은 여전히 ​​유효하지 않습니다. 물론, 모든 것을'byte []'배열로 먼저 읽을 수는 있지만,'mark()'와'reset()'을 쓰면 어떨까요? 코드가 기존 배열에서만 작동한다면'InputStream'을 다룰 필요가 없습니다. 그냥 배열을 사용하십시오. – Holger

+0

적어도 지금까지 시도한 모든 경우에 대해 ByteArrayInputStream()에 대한 재설정이 작동하기 때문에 여전히 올바르지 않습니다. 그리고이 "readLimit"은 무엇이며 어떻게 매번 그 설정을 제안합니까? 이 바이트의 총 수를 참조하거나 다른 것입니까? – ha9u63ar