ByteBuffer ใช้ใน Java คืออะไร [ปิด]


199

แอปพลิเคชันตัวอย่างสำหรับ a ByteBufferใน Java มีอะไรบ้าง โปรดแสดงรายการตัวอย่างสถานการณ์ที่ใช้สิ่งนี้ ขอบคุณ!


1
การบีบอัดของ Apache Hadoop (เช่นตัวแปลงสัญญาณ zlib) ใช้ ByteBuffer จาก jave.nio
nikk

เหมาะสำหรับส่งข้อมูลไปยัง GPU
พิกเซล

คำตอบ:


138

นี่เป็นคำอธิบายที่ดีเกี่ยวกับการใช้งานและข้อบกพร่อง คุณจำเป็นต้องใช้มันทุกครั้งที่คุณต้องทำ I / O ระดับต่ำอย่างรวดเร็ว หากคุณกำลังจะใช้โปรโตคอล TCP / IP หรือหากคุณกำลังเขียนฐานข้อมูล (DBMS) คลาสนี้จะมีประโยชน์


3
มันมีประโยชน์ทุกที่ในเว็บไซต์ที่มีปริมาณการใช้งานสูงที่พัฒนาโดยใช้ Java & Cassandra DB หรือไม่?
Aklin

1
หลังจากการค้นหาอย่างรวดเร็วดูเหมือนว่าใช่ Cassandra ใช้ ByteBuffer: mail-archive.com/commits@cassandra.apache.org/msg14967.html หากคุณสงสัยเกี่ยวกับเว็บไซต์ดิบอาจมี แต่โดยทั่วไปแล้วเป็นเพียง จะใช้เว็บไซต์ทางอ้อม - โดยใช้เครื่องมือเช่น
คาสซานดรา

1
ไม่ใช่ลิงก์ที่ไม่ดีขอบคุณ ต้องการที่จะเพิ่มหนึ่งนี้ฉันพบว่ามีประโยชน์ - worldmodscode.wordpress.com/2012/12/14/ …
Peter Perháč

ลิงก์แย่ฉันกลัว ...
RoyalBigMack

96

คลาส ByteBuffer มีความสำคัญเนื่องจากเป็นพื้นฐานสำหรับการใช้งานช่องทางใน Java คลาสByteBufferกำหนดหกหมวดหมู่ของการดำเนินการตามบัฟเฟอร์ไบต์ตามที่ระบุไว้ในเอกสาร Java 7 :

  • วิธีรับและใส่ค่าสัมบูรณ์และสัมพัทธ์ที่อ่านและเขียนไบต์เดียว

  • วิธีการรับจำนวนมากที่สัมพันธ์ที่ถ่ายโอนลำดับที่ต่อเนื่องของไบต์จากบัฟเฟอร์นี้ลงในอาร์เรย์

  • วิธีใส่จำนวนมากแบบสัมพันธ์ที่ถ่ายโอนลำดับที่ต่อเนื่องกันของไบต์จากอาร์เรย์ไบต์หรือบัฟเฟอร์ไบต์อื่น ๆ ลงในบัฟเฟอร์นี้

  • วิธีรับและใส่ค่าสัมบูรณ์และสัมพัทธ์ที่อ่านและเขียนค่าของชนิดดั้งเดิมอื่น ๆ แปลพวกเขาไปและกลับจากลำดับของไบต์ตามลำดับไบต์เฉพาะ

  • วิธีการในการสร้างบัฟเฟอร์มุมมองซึ่งอนุญาตให้ดูบัฟเฟอร์ไบต์เป็นบัฟเฟอร์ที่มีค่าประเภทอื่น ๆ ดั้งเดิม และ

  • วิธีการในการกระชับ , การทำซ้ำและหั่นบัฟเฟอร์ไบต์

Example code : Putting Bytes into a buffer.

    // Create an empty ByteBuffer with a 10 byte capacity
    ByteBuffer bbuf = ByteBuffer.allocate(10);

    // Get the buffer's capacity
    int capacity = bbuf.capacity(); // 10

    // Use the absolute put(int, byte).
    // This method does not affect the position.
    bbuf.put(0, (byte)0xFF); // position=0

    // Set the position
    bbuf.position(5);

    // Use the relative put(byte)
    bbuf.put((byte)0xFF);

    // Get the new position
    int pos = bbuf.position(); // 6

    // Get remaining byte count
    int rem = bbuf.remaining(); // 4

    // Set the limit
    bbuf.limit(7); // remaining=1

    // This convenience method sets the position to 0
    bbuf.rewind(); // remaining=7

56
เป็นกลุ่มของความคิดเห็นนี้ถูกคัดลอกจากJava 7 เอกสาร
Janus Troelsen

6
หากคุณไม่ได้รับผลข้างเคียงที่ไม่ชัดเจนฉันเชื่อว่าคุณอาจใช้วิธีการที่ผิดสำหรับการใส่แบบสมบูรณ์ ดูเหมือนว่า Javadoc จะระบุว่าการวางแบบสัมบูรณ์ต้องใช้ค่าดัชนี
Chuck Wolber

6
แม้ว่ามันจะเป็นเพียงสำเนาของ api doc แต่มันก็น่ากังวลว่าคะแนนของมัน bcs บางคนดูเหมือนจะขี้เกียจเกินไปที่จะดูมัน
คริส

1
มีข้อผิดพลาดในหนึ่งในตัวอย่าง "ใส่แน่นอน" คิดถึงพารามิเตอร์แรกซึ่งแสดงถึงดัชนี (0 ในกรณีนี้)
bvdb

21

Java IO ที่ใช้ stream oriented APIs ดำเนินการโดยใช้บัฟเฟอร์เป็นที่เก็บข้อมูลชั่วคราวภายในพื้นที่ผู้ใช้ ข้อมูลที่อ่านจากดิสก์โดย DMA จะถูกคัดลอกไปยังบัฟเฟอร์ในพื้นที่เคอร์เนลก่อนแล้วจึงโอนไปยังบัฟเฟอร์ในพื้นที่ผู้ใช้ ดังนั้นจึงมีค่าใช้จ่าย การหลีกเลี่ยงมันสามารถทำให้ได้ประสิทธิภาพที่เพิ่มขึ้นอย่างมาก

เราสามารถข้ามบัฟเฟอร์ชั่วคราวนี้ในพื้นที่ผู้ใช้หากมีวิธีเข้าถึงบัฟเฟอร์ในพื้นที่เคอร์เนลโดยตรง Java NIO จัดเตรียมวิธีในการทำเช่นนั้น

ByteBufferเป็นหนึ่งในหลายบัฟเฟอร์ที่จัดทำโดย Java NIO มันเป็นเพียงภาชนะหรือถังเก็บเพื่ออ่านข้อมูลจากหรือเขียนข้อมูลไป พฤติกรรมดังกล่าวสามารถทำได้โดยการจัดสรรบัฟเฟอร์โดยตรงโดยใช้allocateDirect()API บนบัฟเฟอร์

เอกสาร Java ของ Byte Buffer มีข้อมูลที่เป็นประโยชน์


14

ใน Android คุณสามารถสร้างบัฟเฟอร์ที่ใช้ร่วมกันระหว่าง C ++ และ Java (ด้วยวิธี directAlloc) และจัดการมันทั้งสองด้าน


13

นี่คือบทความที่ยอดเยี่ยมที่อธิบายประโยชน์ของ ByteBuffer ต่อไปนี้เป็นประเด็นสำคัญในบทความ:

  • ประโยชน์แรกของ ByteBuffer โดยไม่คำนึงว่าจะเป็นทางตรงหรือทางอ้อมคือการเข้าถึงแบบสุ่มที่มีประสิทธิภาพของข้อมูลไบนารีที่มีโครงสร้าง (เช่น IO ระดับต่ำตามที่ระบุไว้ในคำตอบข้อใดข้อหนึ่ง) ก่อนหน้า Java 1.4 การอ่านข้อมูลดังกล่าวสามารถใช้ DataInputStream แต่ไม่มีการเข้าถึงแบบสุ่ม

ต่อไปนี้เป็นสิทธิประโยชน์สำหรับ ByteBuffer / MappedByteBuffer โดยตรง โปรดทราบว่าบัฟเฟอร์โดยตรงถูกสร้างขึ้นนอกฮีป:

  1. ไม่ได้รับผลกระทบจาก gc cycles : บัฟเฟอร์โดยตรงจะไม่ถูกย้ายระหว่างรอบการรวบรวมขยะเนื่องจากอยู่นอก heap เทคโนโลยีการแคชBigMemoryของTerraCotaดูเหมือนจะพึ่งพาข้อได้เปรียบนี้เป็นอย่างมาก หากพวกเขาอยู่ในกองมันจะชะลอตัวลง gc เวลาหยุดชั่วคราว

  2. การเพิ่มประสิทธิภาพ : ในสตรีม IO การอ่านเพื่อเรียกใช้จะทำให้เกิดการเรียกใช้ระบบซึ่งต้องการการสลับบริบทระหว่างผู้ใช้ไปยังโหมดเคอร์เนลและในทางกลับกันซึ่งจะมีค่าใช้จ่ายสูงโดยเฉพาะหากไฟล์ถูกเข้าถึงอย่างต่อเนื่อง อย่างไรก็ตามด้วยการแมปหน่วยความจำการสลับบริบทนี้จะลดลงเนื่องจากข้อมูลมีแนวโน้มที่จะพบได้ในหน่วยความจำ (MappedByteBuffer) หากข้อมูลมีอยู่ในหน่วยความจำข้อมูลจะถูกเข้าถึงโดยตรงโดยไม่ต้องเรียกใช้ OS เช่นไม่มีการสลับบริบท

โปรดทราบว่า MappedByteBuffers นั้นมีประโยชน์มากโดยเฉพาะอย่างยิ่งหากไฟล์มีขนาดใหญ่และกลุ่มบล็อกจำนวนน้อยสามารถเข้าถึงได้บ่อยขึ้น

  1. การแชร์เพจ : ไฟล์ที่แม็พหน่วยความจำสามารถแบ่งใช้ระหว่างกระบวนการขณะที่ถูกจัดสรรในพื้นที่หน่วยความจำเสมือนของกระบวนการและสามารถแบ่งใช้ระหว่างกระบวนการได้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.