java.nio

Inhalt


Buffer

Beispiel für einen Buffer für Objekte

ObjectBuffer Definition

  private ByteBuffer bb;
  public ObjectBuffer(ByteBuffer bb) {
      this.bb = bb;
  }

put() Methode

public void put( Object obj ) throws IOException {
      ByteArrayOutputStream os  = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream( os );
      oos.writeObject( obj );
      oos.close();
      bb.put( os.toByteArray() );
}

get() Methode

public Object get() throws IOException, ClassNotFoundException {
      int pos;
      int rem;
      byte[] cont;
      if ( bb.hasArray() ) {
         cont = bb.array();
         pos = bb.position();
         rem = bb.remaining();
      } else {  // could be inefficient
         bb.mark();
         ByteBuffer bba = ByteBuffer.allocate( bb.remaining() );
         bba.clear();
         bba.put( bb );
         bba.rewind();
         cont = bba.array();
         pos = bba.position();
         rem = bba.remaining();
         bb.reset();
      }
      ByteArrayInputStream is  
            = new ByteArrayInputStream( cont, pos, rem );
      int read = is.available();
      ObjectInputStream ois = new ObjectInputStream( is );
      Object obj = ois.readObject();
      ois.close();
      read = read - is.available();
      bb.position( bb.position() + read );
      return obj;
}

Source: ObjectBuffer.java

Channel

Beispiel für einen Channel mit Buffer für Objekte

ObjectBufferChannel Definition

  final ByteBuffer hbb;
  final ObjectBuffer ob;
  final SocketChannel soc;
  public ObjectBufferChannel(SocketChannel s, int cap) 
                             throws IOException {
     soc = s;
     hbb = ByteBuffer.allocate(cap);
     ob = new ObjectBuffer( hbb );
  }

send() Methode

public void send(Object v) throws IOException {
  synchronized (hbb) {
      hbb.clear();
      ob.put(v);
      hbb.flip();
      soc.write( hbb );
  }
}

receive() Methode

public Object receive() throws IOException, 
                               ClassNotFoundException {
  Object v = null;
  synchronized (hbb) {
      hbb.clear();
      soc.read( hbb );
      hbb.flip();
      v = ob.get();
  }
  return v;
}

Source: ObjectBufferChannel.java

FileLocks

Selector

Die Arbeit mit nicht blockierenden Channel Operationen verläuft im Wesentlichen in folgenden 3 Schritten:

  1. registrieren, Ereignisse anfordern und select() aufrufen
  2. prüfen der Ereignisse und eventueller Nebenbedingungen (guards in CSP)
  3. Durchführen und / oder Abschliessen der Operationen

Beispiel für nicht blockierende Channel Operationen

Initialisierung

  private Selector selector = null;
  private SelectionKey serverkey = null;
  private ServerSocketChannel server = null;

  public ChannelFactoryNioBuffer(int port) {
    try {
        selector = Selector.open();

        server = ServerSocketChannel.open();
        server.configureBlocking(false);
        serverkey = server.register(selector,SelectionKey.OP_ACCEPT);
        server.socket().bind( new InetSocketAddress(port) );
    } catch (BindException e) { 
        serverkey.cancel();
    } ...
  }

Behandeln der accept-Ereignisse

ObjectBufferChannel c = null;
SocketChannel s;

while (c == null) {
      selector.select(); // blocking

      Set<SelectionKey> keys = selector.selectedKeys();
      for ( SelectionKey k: keys ) {
          if ( k == serverkey ) {
             if ( k.isAcceptable() ) { // just in case
                keys.remove(k);
                s = server.accept();
                s.configureBlocking(true);
                c = new ObjectBufferChannel( s, capacity );
                break; // ignore other keys
             }
          } else { // ignore client keys
             selector.wakeup();
          }
      }
}

Behandeln der connect-Ereignisse

SelectionKey clientkey = null;
ObjectBufferChannel c = null;
SocketChannel client;

while (c == null) {
      client = SocketChannel.open();
      client.configureBlocking(false);
      clientkey = client.register(selector,SelectionKey.OP_CONNECT);
      client.connect( new InetSocketAddress(host,port) );

      selector.select(); // blocking

      Set<SelectionKey> keys = selector.selectedKeys();
      for ( SelectionKey k: keys ) {
          if ( k == clientkey ) {
             if ( k.isConnectable() ) { // if server ready
                keys.remove(k);
                k.cancel();     // required to make blockable
                client = (SocketChannel) k.channel();
                client.finishConnect();
                client.configureBlocking(true);
                c = new ObjectBufferChannel( client, capacity );
                break; // ignore other keys
             }
          } else { // ignore server keys
             selector.wakeup();
          }
      }
}

Source: ChannelFactoryNioBuffer.java


© Universität Mannheim, Rechenzentrum, 2005-2006.

Heinz Kredel

Last modified: Sat Dec 10 11:53:34 CET 2005