2009-02-20 36 views
5

Cách hiệu quả nhất để đưa nhiều byte nhất có thể từ một ByteBuffer bbuf_src vào một ByteBuffer bbuf_dest khác (cũng như biết có bao nhiêu byte được chuyển)? Tôi đang cố gắng bbuf_dest.put(bbuf_src) nhưng có vẻ như muốn ném một BufferOverflowException và tôi không thể nhận được javadocs từ Sun ngay bây giờ (vấn đề mạng) khi tôi cần chúng. > :(arghchuyển byte từ một ByteBuffer sang một ByteBuffer khác


chỉnh sửa:. Darnit, @ phương pháp (sử dụng đặt() từ mảng sự ủng hộ của bbuf_src) của Richard sẽ không hoạt động nếu bbuf_src là một bộ đệm ReadOnly, như bạn không thể có được quyền truy cập vào rằng mảng. những gì tôi có thể làm trong trường hợp đó ???

+0

Tôi nghĩ bạn nên chia thành hai câu hỏi. – GEOCHET

+0

nửa còn lại đã được chuyển đến đây: http://stackoverflow.com/questions/570218/downloading-sun-javadocs-mirror-websites –

Trả lời

1

OK, tôi đã thích nghi @ Richard câu trả lời:

public static int transferAsMuchAsPossible(
        ByteBuffer bbuf_dest, ByteBuffer bbuf_src) 
{ 
    int nTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
    if (nTransfer > 0) 
    { 
    bbuf_dest.put(bbuf_src.array(), 
        bbuf_src.arrayOffset()+bbuf_src.position(), 
        nTransfer); 
    bbuf_src.position(bbuf_src.position()+nTransfer); 
    } 
    return nTransfer; 
} 

và một bài kiểm tra để chắc chắn rằng nó hoạt động:

public static boolean transferTest() 
{ 
    ByteBuffer bb1 = ByteBuffer.allocate(256); 
    ByteBuffer bb2 = ByteBuffer.allocate(50); 
    for (int i = 0; i < 100; ++i) 
    { 
     bb1.put((byte)i); 
    } 
    bb1.flip(); 
    bb1.position(5); 
    ByteBuffer bb1a = bb1.slice(); 
    bb1a.position(2); 
    // bb3 includes the 5-100 range 
    bb2.put((byte)77); 
    // something to see this works when bb2 isn't empty 
    int n = transferAsMuchAsPossible(bb2, bb1a); 
    boolean itWorked = (n == 49); 

    if (bb1a.position() != 51) 
     itWorked = false; 
    if (bb2.position() != 50) 
     itWorked = false; 
    bb2.rewind(); 
    if (bb2.get() != 77) 
     itWorked = false; 
    for (int i = 0; i < 49; ++i) 
    { 
     if (bb2.get() != i+7) 
     { 
      itWorked = false; 
      break; 
     } 
    } 
    return itWorked; 
} 
1

bạn sẽ có được BufferOverflowException vì bbuf_dest của bạn không đủ lớn.

bạn sẽ cần phải sử dụng bbuf_dest.remaining() để tìm hiểu số lượng tối đa các byte bạn có thể chuyển từ bbuf_src:

int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
bbuf_dest.put(bbuf_src.array(), 0, maxTransfer); 
+0

Ah. Điều đó rất hữu ích. Tôi nghĩ tôi biết phải làm gì bây giờ. Cảm ơn. Nhưng lưu ý rằng câu trả lời của bạn sẽ không hoạt động nếu bbuf_src là một bộ đệm xem cho bộ đệm khác. Tôi nghĩ rằng tôi có thể thích ứng với nó mặc dù. –

+0

(hoặc nếu vị trí của bbuf_src là> 0) –

+0

... và tôi cũng phải cập nhật vị trí của bbuf_src. –

8

Như bạn đã phát hiện ra, nhận được sự ủng hộ mảng không phải lúc nào làm việc (nó không thành công cho bộ đệm chỉ đọc, bộ đệm trực tiếp và bộ đệm tệp được ánh xạ bộ nhớ). Cách tốt hơn là sao chép bộ đệm nguồn của bạn và đặt giới hạn mới cho lượng dữ liệu bạn muốn chuyển:

int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
// use a duplicated buffer so we don't disrupt the limit of the original buffer 
ByteBuffer bbuf_tmp = bbuf_src.duplicate(); 
bbuf_tmp.limit (bbuf_tmp.position() + maxTransfer); 
bbuf_dest.put (bbuf_tmp); 

// now discard the data we've copied from the original source (optional) 
bbuf_src.position(bbuf_src.position() + maxTransfer); 
+0

Nhưng Oracle nói rằng giới hạn phải là "không lớn hơn dung lượng bộ đệm". Sao chép một bộ đệm sẽ nhân đôi dung lượng của nó, phải không? –

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