Java Tutorial/File/ByteBuffer

Материал из Java эксперт
Перейти к: навигация, поиск

A ByteBuffer is a fixed-capacity buffer that holds byte values.

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   
   byte[] bytes = new byte[10];
   ByteBuffer buf = ByteBuffer.wrap(bytes);
 }

}</source>





Allocation automatically zeroes the ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
    int i = 0;
   while (i++ < bb.limit())
     if (bb.get() != 0)
       System.out.println("nonzero");
   System.out.println("i = " + i);
 }

}</source>





ByteBuffer.hasRemaining()

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, 0, 0, 0, 0, "a" });
   bb.rewind();
   System.out.println("Byte Buffer");
   while (bb.hasRemaining())
     System.out.println(bb.position() + " -> " + bb.get());
 }

} /**/</source>



Byte Buffer
0 -> 0
1 -> 0
2 -> 0
3 -> 0
4 -> 0
5 -> 0
6 -> 0
7 -> 97


Converting Between a ByteBuffer an a Byte Array

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   // Create a ByteBuffer from a byte array
   byte[] bytes = new byte[10];
   ByteBuffer buf = ByteBuffer.wrap(bytes);
 }

}</source>





Converting text to and from ByteBuffers

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) throws Exception {
   FileChannel fc = new FileOutputStream("data2.txt").getChannel();
   fc.write(ByteBuffer.wrap("Some text".getBytes()));
   fc.close();
   fc = new FileInputStream("data2.txt").getChannel();
   ByteBuffer buff = ByteBuffer.allocate(BSIZE);
   fc.read(buff);
   buff.flip();
   System.out.println(buff.asCharBuffer());
   // Decode using this system"s default Charset:
   buff.rewind();
   String encoding = System.getProperty("file.encoding");
   System.out.println("Decoded using " + encoding + ": " + Charset.forName(encoding).decode(buff));
   // Or, we could encode with something that will print:
   fc = new FileOutputStream("data2.txt").getChannel();
   fc.write(ByteBuffer.wrap("Some text".getBytes("UTF-16BE")));
   fc.close();
 }

} /**/</source>



????
Decoded using Cp1252: Some text


Converting text to and from ByteBuffers with UTF-16BE

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) throws Exception {
   FileChannel fc = new FileOutputStream("data2.txt").getChannel();
   fc.write(ByteBuffer.wrap(
     "Some text".getBytes("UTF-16BE")));
   fc.close();
   ByteBuffer buff = ByteBuffer.allocate(BSIZE);
   // Now try reading again:
   fc = new FileInputStream("data2.txt").getChannel();
   buff.clear();
   fc.read(buff);
   buff.flip();
   System.out.println(buff.asCharBuffer());
   
 }

} /**/</source>



Some text


Create a ByteBuffer using a byte array

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   
   byte[] bytes = new byte[10];
   ByteBuffer buf = ByteBuffer.wrap(bytes);
 }

}</source>





Create a direct (memory-mapped) ByteBuffer with a 10 byte capacity.

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
 }

}</source>





Create a non-direct ByteBuffer with a 10 byte capacity

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocate(10);
 }

}</source>





Endian differences and data storage

   <source lang="java">

import java.nio.ByteBuffer; import java.nio.ByteOrder; public class MainClass {

 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.wrap(new byte[12]);
   bb.asCharBuffer().put("abcdef");
   System.out.println(toString(bb.array()));
   bb.rewind();
   bb.order(ByteOrder.BIG_ENDIAN);
   bb.asCharBuffer().put("abcdef");
   System.out.println(toString(bb.array()));
   bb.rewind();
   bb.order(ByteOrder.LITTLE_ENDIAN);
   bb.asCharBuffer().put("abcdef");
   System.out.println(toString(bb.array()));
 }
 public static String toString(byte[] a) {
   StringBuffer result = new StringBuffer("[");
   for (int i = 0; i < a.length; i++) {
     result.append(a[i]);
     if (i < a.length - 1)
       result.append(", ");
   }
   result.append("]");
   return result.toString();
 }

} /*

* [0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] [0, 97, 0, 98, 0, 99, 0, 100,
* 0, 101, 0, 102] [97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
*/</source>
   
  
 
  



Get remaining byte count in a ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   int rem = buf.remaining();
 }

}</source>





Get the ByteBuffer"s capacity

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   int capacity = buf.capacity(); // 10
 }

}</source>





Putting Bytes into a ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer bbuf = ByteBuffer.allocate(10);
   int capacity = bbuf.capacity(); // 10
   System.out.println(capacity);
   bbuf.put((byte) 0xFF); 
   bbuf.position(5);
   bbuf.put((byte) 0xFF);
   int pos = bbuf.position(); 
   int rem = bbuf.remaining();
   bbuf.limit(7); 
   bbuf.rewind(); 
 }

}</source>





Read from a channel with a ByteBuffer

   <source lang="java">

import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; public class Main {

 public static void main(String[] argv) throws Exception {
   ReadableByteChannel channel = new FileInputStream("infile").getChannel();
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   int numRead = 0;
   while (numRead >= 0) {
     buf.rewind();
     numRead = channel.read(buf);
     buf.rewind();
     for (int i = 0; i < numRead; i++) {
       byte b = buf.get();
     }
   }
 }

}</source>





Retrieve all bytes in the buffer

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   byte[] bytes = new byte[10];
   ByteBuffer buf = ByteBuffer.wrap(bytes);
   buf.clear();
   bytes = new byte[buf.capacity()];
   buf.get(bytes, 0, bytes.length);
 }

}</source>





Retrieve bytes between the position and limit

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   byte[] bytes = new byte[10];
   ByteBuffer buf = ByteBuffer.wrap(bytes);
   bytes = new byte[buf.remaining()];
   buf.get(bytes, 0, bytes.length);
 }

}</source>





Rewind a ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asCharBuffer().put("Howdy!");
   char c;
   while ((c = bb.getChar()) != 0)
     System.out.print(c + " ");
   System.out.println();
   bb.rewind();
   // Store and read a short:
   bb.asShortBuffer().put((short) 471142);
   System.out.println(bb.getShort());
 }

} /**/</source>



H o w d y ! 
12390


Set the limit for ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   buf.limit(7); // remaining=1
 }

}</source>





Set the position

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   buf.position(5);
 }

}</source>





Store and read a char array

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asCharBuffer().put("Howdy!");
   char c;
   while ((c = bb.getChar()) != 0)
     System.out.print(c + " ");
   System.out.println();
 }

}//</source>



H o w d y !


Store and read a double

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asDoubleBuffer().put(99471142);
   System.out.println(bb.getDouble());
 }

} /*

  • /</source>



9.9471142E7


Store and read a float

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asFloatBuffer().put(99471142);
   System.out.println(bb.getFloat());
 }

} /**/</source>



9.9471144E7


Store and read a long

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asLongBuffer().put(99472342341142L);
   System.out.println(bb.getLong());
 }

} /**/</source>



99472342341142


Store and read an int

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asIntBuffer().put(99471142);
   System.out.println(bb.getInt());
 }

} /**/</source>



99471142


Store and read a short

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 private static final int BSIZE = 1024;
 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.allocate(BSIZE);
   bb.asCharBuffer().put("Howdy!");
   char c;
   while ((c = bb.getChar()) != 0)
     System.out.print(c + " ");
   System.out.println();
   bb.rewind();
   // Store and read a short:
   bb.asShortBuffer().put((short) 471142);
   System.out.println(bb.getShort());
 }

} /**/</source>



H o w d y ! 
12390


Test views of long elements in a ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; import java.nio.ByteOrder; /**

* Test views of long elements in a ByteBuffer.
* 
*/

public class MainClass {

 public static void main(String[] argv) throws Exception {
   ByteBuffer bb = ByteBuffer.allocate(20);
   bb.put((byte) 0x07);
   bb.put((byte) 0x08);
   bb.put((byte) 0x09);
   bb.put((byte) 0x10);
   bb.put((byte) 0x11);
   bb.put((byte) 0x12);
   bb.put((byte) 0x13);
   bb.put((byte) 0x14);
   bb.position(1).limit(5);
   bb.mark();
   System.out.println("Expect an exception here");
   System.out.println("" + bb.order().toString() + ": " + bb.getLong());
 }

} /**/</source>



Expect an exception here
Exception in thread "main" java.nio.BufferUnderflowException
  at java.nio.Buffer.nextGetIndex(Buffer.java:404)
  at java.nio.HeapByteBuffer.getLong(HeapByteBuffer.java:387)
  at MainClass.main(MainClass.java:25)


This convenience method sets the position to 0

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   buf.rewind(); // remaining=7
 }

}</source>





Use FileChannel and ByteBuffer to Copy File

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class Main {

 public static void main(String[] args) throws Exception {
   String source = "s.txt";
   String destination = "d.txt";
   FileInputStream fis = new FileInputStream(source);
   FileOutputStream fos = new FileOutputStream(destination);
   FileChannel fci = fis.getChannel();
   FileChannel fco = fos.getChannel();
   ByteBuffer buffer = ByteBuffer.allocate(1024);
   while (true) {
     int read = fci.read(buffer);
     if (read == -1)
       break;
     buffer.flip();
     fco.write(buffer);
     buffer.clear();
   }
 }

}</source>





Use the absolute get().

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   byte b = buf.get(5); // position=0
 }

}</source>





Use the relative get()

   <source lang="java">

import java.nio.ByteBuffer; public class Main {

 public static void main(String[] argv) throws Exception {
   ByteBuffer buf = ByteBuffer.allocateDirect(10);
   byte b = buf.get();
 }

}</source>





Use while loop to read a ByteBuffer

   <source lang="java">

import java.nio.ByteBuffer; public class MainClass {

 public static void main(String[] args) {
   ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, 0, 0, 0, 0, "a" });
   bb.rewind();
   System.out.println("Byte Buffer");
   while (bb.hasRemaining())
     System.out.println(bb.position() + " -> " + bb.get());
 }

} /**/</source>



Byte Buffer
0 -> 0
1 -> 0
2 -> 0
3 -> 0
4 -> 0
5 -> 0
6 -> 0
7 -> 97