Java Tutorial/File/ByteBuffer
Содержание
- 1 A ByteBuffer is a fixed-capacity buffer that holds byte values.
- 2 Allocation automatically zeroes the ByteBuffer
- 3 ByteBuffer.hasRemaining()
- 4 Converting Between a ByteBuffer an a Byte Array
- 5 Converting text to and from ByteBuffers
- 6 Converting text to and from ByteBuffers with UTF-16BE
- 7 Create a ByteBuffer using a byte array
- 8 Create a direct (memory-mapped) ByteBuffer with a 10 byte capacity.
- 9 Create a non-direct ByteBuffer with a 10 byte capacity
- 10 Endian differences and data storage
- 11 Get remaining byte count in a ByteBuffer
- 12 Get the ByteBuffer"s capacity
- 13 Putting Bytes into a ByteBuffer
- 14 Read from a channel with a ByteBuffer
- 15 Retrieve all bytes in the buffer
- 16 Retrieve bytes between the position and limit
- 17 Rewind a ByteBuffer
- 18 Set the limit for ByteBuffer
- 19 Set the position
- 20 Store and read a char array
- 21 Store and read a double
- 22 Store and read a float
- 23 Store and read a long
- 24 Store and read an int
- 25 Store and read a short
- 26 Test views of long elements in a ByteBuffer
- 27 This convenience method sets the position to 0
- 28 Use FileChannel and ByteBuffer to Copy File
- 29 Use the absolute get().
- 30 Use the relative get()
- 31 Use while loop to read a ByteBuffer
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