2012-01-07 17 views
7

Luồng đầu vào/đầu ra gzip không hoạt động trên bộ đệm trực tiếp của Java.nén trên bộ đệm trực tiếp java nio

Có bất kỳ triển khai thuật toán nén nào hoạt động trực tiếp trên bộ đệm trực tiếp không?

Bằng cách này, sẽ không có phí sao chép bộ đệm trực tiếp vào mảng byte java để nén.

+1

Nén mà không phải trả phí là không thể. Các bộ đệm trực tiếp, theo định nghĩa, _ "một vùng chứa cho một lượng dữ liệu cố định của một kiểu nguyên thủy cụ thể" _. Một sự chuyển đổi như một nén hoặc mã hóa phải được thực hiện bên ngoài bộ đệm. –

+1

tôi hiểu. tôi chỉ muốn thực hiện nén mà không bị thêm hình phạt khi sao chép toàn bộ mảng đệm trực tiếp vào mảng byte java – pdeva

+3

GZIPInputStream không tạo bản sao - nó truyền trực tiếp ra khỏi tệp (dựa trên việc kiểm tra nguồn). Vì vậy, tôi tưởng tượng nó có lẽ nhanh hơn việc tạo bộ đệm trực tiếp của riêng bạn và ánh xạ một tệp cho nó. Nếu bạn thực sự muốn sử dụng một bộ đệm trực tiếp, bạn có thể viết InputStream của riêng bạn mà luồng từ bộ đệm của bạn ... –

Trả lời

2

Tôi không có ý làm giảm đi câu hỏi của bạn, nhưng có phải là thực sự là một điểm tối ưu hóa tốt trong chương trình của bạn không? Bạn đã xác minh với một hồ sơ mà bạn thực sự có một vấn đề? Câu hỏi của bạn như đã nêu có nghĩa là bạn chưa thực hiện bất kỳ nghiên cứu nào, nhưng chỉ đơn thuần là đoán rằng bạn sẽ có một vấn đề hiệu suất hoặc bộ nhớ bằng cách phân bổ một byte []. Vì tất cả các câu trả lời trong chuỗi này có khả năng là hack của một số loại, bạn nên thực sự xác minh rằng bạn thực sự có một vấn đề trước khi sửa chữa nó.

Quay lại câu hỏi, nếu bạn muốn nén dữ liệu "tại chỗ" trên một ByteBuffer, câu trả lời là không, không có khả năng để làm điều đó được xây dựng trong Java.

Nếu bạn phân bổ đệm của bạn như sau:

byte[] bytes = getMyData(); 
ByteBuffer buf = ByteBuffer.wrap(bytes); 

Bạn có thể lọc byte của bạn [] thông qua một ByteBufferInputStream là câu trả lời trước đề nghị.

+0

tôi chấp nhận câu trả lời này, nhưng vẫn chờ đợi cung cấp giải pháp, ví dụ dưới dạng thư viện hoạt động bằng cách sử dụng jni trên bộ đệm byte. – pdeva

+0

Tôi đã tò mò về câu hỏi này bởi vì tôi muốn tìm một cách để chuyển đổi một thư mục thành một tệp zip trong tên duy nhất tại chỗ để xóa nhanh các thư mục lớn. –

+1

tránh sao chép dữ liệu hầu như luôn là một tăng đáng kể cho hiệu suất. Tuy nhiên, dữ liệu đã có trong bộ đệm trực tiếp không thể nén mà không bị sao chép trừ khi được thực hiện bởi chính hệ điều hành. – gregw

0

Nếu bạn đang sử dụng ByteBuffers bạn có thể sử dụng một số hàm bao Input/OutputStream đơn giản như thế này:

public class ByteBufferInputStream extends InputStream { 

    private ByteBuffer buffer = null; 

    public ByteBufferInputStream(ByteBuffer b) { 
     this.buffer = b; 
    } 

    @Override 
    public int read() throws IOException { 
     return (buffer.get() & 0xFF); 
    } 
} 

public class ByteBufferOutputStream extends OutputStream { 

    private ByteBuffer buffer = null; 

    public ByteBufferOutputStream(ByteBuffer b) { 
     this.buffer = b; 
    } 

    @Override 
    public void write(int b) throws IOException { 
     buffer.put((byte)(b & 0xFF)); 
    } 

} 

Test:

ByteBuffer buffer = ByteBuffer.allocate(1000); 
ByteBufferOutputStream bufferOutput = new ByteBufferOutputStream(buffer); 
GZIPOutputStream output = new GZIPOutputStream(bufferOutput); 
output.write("stackexchange".getBytes()); 
output.close(); 

buffer.position(0); 

byte[] result = new byte[ 1000 ]; 

ByteBufferInputStream bufferInput = new ByteBufferInputStream(buffer); 
GZIPInputStream input = new GZIPInputStream(bufferInput); 
input.read(result); 

System.out.println(new String(result)); 
+3

thậm chí gói dấu thăng tiến vào luồng không hỗ trợ. nội bộ (đôi khi hai lần), sorta đánh bại mục đích của bytebuffer – bestsss

+0

Xin lỗi nhưng tôi không hiểu, khi nào bản sao đó xảy ra? Tôi đã kiểm tra lại mã cho InputStream, OutputStream và thậm chí cả các lớp GZIP và không thể tìm thấy bất kỳ bản sao nào. –

+0

đó là cách nó hoạt động, hãy kiểm tra InflatedInputStream và hàm gốc phải sao chép (hoặc ghim, phụ thuộc vào JVM/GC) byte [] để chuyển nó tới zlib – bestsss