2010-02-02 31 views
6

Một người dùng tải lên một tệp lớn vào trang web của tôi và tôi muốn lưu trữ tệp và lưu trữ nó trong một blob. Vì vậy, tôi có một InputStream không nén và blob muốn một InputStream. Tôi biết làm thế nào để nén một InputStream đến một Outputstream bằng cách sử dụng GZIPOutputStream, nhưng làm thế nào để tôi đi từ gzip'ed OutputStream trở lại InputStream cần thiết bởi blob.Làm thế nào tôi có thể chuyển đổi một InputStream không nén thành một Gzip'ed InputStream một cách hiệu quả?

Cách duy nhất tôi có thể tìm thấy liên quan đến việc sử dụng ByteArrayOutputStream và sau đó tạo một InputStream mới bằng cách sử dụng toByteArray. Nhưng điều đó có nghĩa là tôi có toàn bộ bản sao của tệp trong bộ nhớ. Và nó sẽ không làm tôi ngạc nhiên nếu việc thực hiện trình điều khiển JDBC chuyển đổi dòng sang một byte [] cũng vì vậy tôi sẽ có hai bản sao trong bộ nhớ.

+0

Nếu bạn không muốn toàn bộ tệp trong bộ nhớ thì hãy ghi vào một tệp. Cách tôi nhìn thấy nó dữ liệu gzip'd cần phải đi đâu đó. –

+0

Tôi đã hy vọng luồng trực tiếp vào blob vì vậy tôi không bao giờ phải có toàn bộ điều trong bộ nhớ. Có vẻ như điều đó sẽ không hoạt động vì tôi cần biết chiều dài tại thời điểm tôi đặt tham số blob. Tôi đoán về mặt kỹ thuật, tôi có thể phát trực tuyến tới một tệp, lấy kích thước của tệp, sau đó sử dụng nó làm luồng nhập vào trở lại blob để tôi không bao giờ cần giữ toàn bộ nội dung trong bộ nhớ. Về cơ bản, tôi sẽ sử dụng hệ thống tệp như bộ nhớ của mình trong trường hợp đó, điều này có thể sẽ hữu ích. –

Trả lời

4

Nếu bạn sử dụng java 1.6, bạn có thể sử dụng java.util.zip.DeflaterInputStream. Theo như tôi có thể nói, điều này thực hiện chính xác những gì bạn muốn. Nếu bạn không thể sử dụng 1,6, bạn sẽ có thể reimplement DeflaterInputStream sử dụng java.util.zip.Deflater. Khi đọc dữ liệu từ BLOB, hãy sử dụng InflaterInputStream làm bộ lọc để lấy lại dữ liệu ban đầu.

+0

Tôi không biết Lớp đó. Điều đó trông giống như giải pháp đúng. Thật không may, việc thực hiện Blob sử dụng chiều dài và DeflaterInputStream luôn luôn trả về 0 hoặc 1. Tôi nghĩ rằng thực tế là tôi cần độ dài có nghĩa là tôi sẽ không thể nén và truyền dữ liệu trực tiếp vào blob bất kể điều gì, vì không thể biết được độ dài cho đến khi quá trình nén hoàn tất. –

+0

@Brian Vì vậy, bạn cần phải vượt qua độ dài cùng với luồng đầu vào khi tạo blob? Không có phương pháp chiều dài trên InputStream, chỉ có một phương thức có sẵn có nghĩa là một cái gì đó hoàn toàn khác với độ dài của luồng. –

+0

có sẵn() dường như trả lại độ dài chính xác trên luồng đầu vào ban đầu (xuất phát từ một bài đăng http). Có lẽ nó dựa trên độ dài nội dung hoặc có thể nó thực sự đọc toàn bộ luồng ở đâu đó ngược dòng trước khi tôi nhận được nó. Nhưng điều đó không giúp ích gì một khi tôi nén nó, bởi vì tôi sẽ không biết kích thước nén cho đến khi tôi đã xử lý toàn bộ luồng, tại thời điểm đó nó nằm trong bộ nhớ vì vậy tôi cũng có thể chuyển nó thành một byte []. –

Các vấn đề liên quan