Java Reference
In-Depth Information
Compacting Buffers
Most writable buffers support a
compact()
method:
public
abstract
ByteBuffer
compact
()
public
abstract
IntBuffer
compact
()
public
abstract
ShortBuffer
compact
()
public
abstract
FloatBuffer
compact
()
public
abstract
CharBuffer
compact
()
public
abstract
DoubleBuffer
compact
()
(If it weren't for invocation chaining, these six methods could have been replaced by
one method in the common
Buffer
superclass.) Compacting shifts any remaining data
in the buffer to the start of the buffer, freeing up more space for elements. Any data that
was in those positions will be overwritten. The buffer's position is set to the end of the
data so it's ready for writing more data.
Compacting is an especially useful operation when you're
copying
—reading from one
channel and writing the data to another using nonblocking I/O. You can read some data
into a buffer, write the buffer out again, then compact the data so all the data that wasn't
written is at the beginning of the buffer, and the position is at the end of the data re‐
maining in the buffer, ready to receive more data. This allows the reads and writes to
be interspersed more or less at random with only one buffer. Several reads can take place
in a row, or several writes follow consecutively. If the network is ready for immediate
output but not input (or vice versa), the program can take advantage of that. This tech‐
nique can be used to implement an echo server as shown in
Example 11-5
. The echo
protocol simply responds to the client with whatever data the client sent. Like chargen,
it's useful for network testing. Also like chargen, echo relies on the client to close the
connection. Unlike chargen, however, an echo server must both read and write from
the connection.
Example 11-5. Echo server
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.util.*
;
import
java.io.IOException
;
public
class
EchoServer
{
public
static
int
DEFAULT_PORT
=
7
;
public
static
void
main
(
String
[]
args
)
{
int
port
;
try
{
port
=
Integer
.
parseInt
(
args
[
0
]);
}
catch
(
RuntimeException
ex
)
{
port
=
DEFAULT_PORT
;