2010-02-02 4 views
6

사용자가 큰 파일을 내 웹 사이트에 업로드하고 파일을 gzip으로 압축하여 blob에 저장하려고합니다. 그래서 나는 압축되지 않은 InputStream을 가지고 있고 BLOB은 InputStream을 원한다. GZIPOutputStream을 사용하여 OutputStream으로 InputStream을 압축하는 방법을 알고 있지만 bzlob에 필요한 InputStream으로 gzip으로 변환 된 OutputStream에서 다시 이동하는 방법은 무엇입니까?어떻게 압축되지 않은 InputStream을 gzip으로 압축 한 InputStream으로 효율적으로 변환 할 수 있습니까?

내가 찾을 수있는 유일한 방법은 ByteArrayOutputStream을 사용하고 toByteArray를 사용하여 새 InputStream을 만드는 것입니다. 하지만 그 파일의 전체 사본을 메모리에 가지고 있다는 뜻입니다. 그리고 JDBC 드라이버 구현이 스트림을 byte []로 변환하면 메모리에 두 개의 사본이 생기게되어 놀라지 않을 것입니다.

+0

전체 파일을 메모리에 저장하지 않으려면 파일에 기록하십시오. 내가 보는 방법은 gzip 된 데이터가 어딘가에 있어야합니다. –

+0

나는 블로프에 직접 들어가기를 원했기 때문에 전체 내용을 메모리에 저장하지 않아도되었습니다. blob 매개 변수를 설정할 때 길이를 알아야하기 때문에 작동하지 않는 것처럼 보입니다. 기술적으로, 파일로 스트리밍하고, 파일의 크기를 얻은 다음, 그것을 블롭에 입력 스트림으로 다시 사용할 수 있으므로 전체 내용을 메모리에 보유 할 필요가 없습니다. 필자는 필연적으로 파일 시스템을 내 메모리로 사용하게 될 것입니다. –

답변

4

자바 1.6을 사용하는 경우 java.util.zip.DeflaterInputStream을 사용할 수 있습니다. 제가 말할 수있는 한, 이것은 당신이 원하는 것입니다. 1.6을 사용할 수 없다면 DeflaterInputStream을 다시 구현할 수 있어야합니다 (java.util.zip.Deflater). BLOB에서 데이터를 다시 읽을 때 InflaterInputStream을 필터로 사용하여 원래 데이터를 다시 가져옵니다.

+0

나는 그 클래스에 대해 몰랐다. 그것은 올바른 해결책처럼 보입니다. 아쉽게도 Blob 구현은 길이를 사용하고 DeflaterInputStream은 항상 0 또는 1을 반환합니다. 길이가 필요하다는 사실은 내가 무엇이든 관계없이 데이터를 압축하여 스트림을 직접 스트리밍 할 수 없다는 것을 의미한다고 생각합니다. 길이는 압축이 완료 될 때까지 알 수 없습니다. –

+0

@Brian 그래서 BLOB를 만들 때 입력 스트림과 함께 길이를 전달해야합니까? InputStream에는 길이 메서드가 없으며 스트림 길이와 완전히 다른 것을 의미하는 메서드 만 사용할 수 있습니다. –

+0

available()은 원래 입력 스트림 (http 게시물에서 오는)에서 올바른 길이를 반환하는 것으로 보입니다. 어쩌면 그것은 내용의 길이에 기반을 두었거나 어쩌면 상류 어딘가에있는 전체 스트림을 실제로 읽었을 것입니다. 하지만 일단 압축을하면 압축이되지 않습니다. 왜냐하면 이미 전체 스트림을 처리 할 때까지 압축 된 크기를 알지 못하기 때문입니다. 메모리에있는 지점에서 바이트로 변환 할 수 있습니다. –

관련 문제