Nio : Buffer

L'histoire informatique montre un perpétuel et cyclique balancement entre abstraction /simplicité et implémentation détaillée/complexité.
L'API java.io avait comme avantage, par rapport à l'existant, de réaliser des entrées/sorties sans se souvier des détails techniques : quel type de flot (fichier, socket, pipe, ...), gestion des tampons, .....
L'API java.nio définit une hiérarchie de classe pour gérer finement des tampons.

ajouter/obtenir des bytes dans un tampon

Source de BufferNio1.java
import java.io.*;
import java.nio.*;

public class BufferNio1
{
  static public void main( String args[] ) throws Exception {
    ByteBuffer buffer = ByteBuffer.allocate( 10 );    
    buffer.put( (byte)'a' );
    buffer.put( (byte)'1' );
    buffer.put( (byte)'b' );
    buffer.flip();
    System.out.println( (char)buffer.get() );
    System.out.println( (char)buffer.get() );
    System.out.println( (char)buffer.get() );
  }
}

EXECUTION
$java BufferNio1
a
1
b

Les lignes de la classe :

"parcourir" un tampon IntBuffer

Source de BufferNio2.java
import java.io.*;
import java.nio.*;

public class BufferNio2
{
  static public void main( String args[] ) throws Exception {
    IntBuffer buffer = IntBuffer.allocate( 10 );    
    for (int i=0; i<buffer.capacity(); ++i) 
      buffer.put(i);    
    buffer.flip();
    while (buffer.hasRemaining()) {
      int j = buffer.get();
      System.out.println( j );
    }
  }
}

EXECUTION
$java BufferNio2
0
1
2
3
4
5
6
7
8
9

Les lignes de la classe :

La "mécanique" des tampons : capacity, limit, position, ...

Source de BufferNio3.java
import java.io.*;
import java.nio.*;
public class BufferNio3
{
  static public void main( String args[] ) throws Exception {
    DoubleBuffer buffer = DoubleBuffer.allocate( 10 );
    
    System.out.println(" buffer capacity = "+buffer.capacity() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.put( 12.3 );
    buffer.put( 4.5 );
    System.out.println("put 12.3 et put 4.5");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.put( 0.678 );
    System.out.println("put 0.678");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.flip();
    System.out.println("flip");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    System.out.println( "get : "+ buffer.get() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    System.out.println( "get : "+ buffer.get() );
    System.out.println( "get : "+ buffer.get() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());

    buffer.rewind();
    System.out.println("rewind");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    System.out.println( "get : "+ buffer.get() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    System.out.println( "get : "+ buffer.get() );
    System.out.println( "get : "+ buffer.get() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
  }
}

EXECUTION
$java BufferNio3
 buffer capacity = 10
 buffer position = 0 limit = 10
put 12.3 et put 4.5
 buffer position = 2 limit = 10
put 0.678
 buffer position = 3 limit = 10
flip
 buffer position = 0 limit = 3
get : 12.3
 buffer position = 1 limit = 3
get : 4.5
get : 0.678
 buffer position = 3 limit = 3
rewind
 buffer position = 0 limit = 3
get : 12.3
 buffer position = 1 limit = 3
get : 4.5
get : 0.678
 buffer position = 3 limit = 3
Les lignes de la classe :

$java BufferNio3
 buffer capacity = 10
 buffer position = 0 limit = 10
put 12.3 et put 4.5
 buffer position = 2 limit = 10
put 0.678
 buffer position = 3 limit = 10
flip
 buffer position = 0 limit = 3
get : 12.3
 buffer position = 1 limit = 3
get : 4.5
get : 0.678
 buffer position = 3 limit = 3
rewind
 buffer position = 0 limit = 3
get : 12.3
 buffer position = 1 limit = 3

La "mécanique" des tampons : clear, dépassement, ...

Source de BufferNio4.java
import java.io.*;
import java.nio.*;
public class BufferNio4
{
  static public void main( String args[] ) throws Exception {
    
    CharBuffer buffer = CharBuffer.allocate( 10 );
    
    System.out.println(" buffer capacity = "+buffer.capacity() );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.put( "abc 3.4 e" );
    System.out.println(" put( \"abc 3.4 e\")");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.flip();
    System.out.println("flip");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    char[] tabChar = new char[5];
    buffer.get(tabChar);
    String CinqChars = new String(tabChar);
    System.out.println( "get(tableau de 5 char) : "+  CinqChars);
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    while (buffer.hasRemaining())
      buffer.get();
    System.out.println( "buffer.hasRemaining() faux " );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.clear();    
    System.out.println( "buffer clear  " );
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
                       
    buffer.put( "xyz" );
    System.out.println(" put( \"xyz\")");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    buffer.flip();
    System.out.println("flip");
    System.out.println(" buffer position = "+buffer.position() 
                       +" limit = "+buffer.limit());
    System.out.println( "essaye get(tableau de 5 char) ");
    buffer.get(tabChar);
                       
  }
}

EXECUTION
$java BufferNio4
 buffer capacity = 10
 buffer position = 0 limit = 10
 put( "abc 3.4 e")
 buffer position = 9 limit = 10
flip
 buffer position = 0 limit = 9
get(tableau de 5 char) : abc 3
 buffer position = 5 limit = 9
buffer.hasRemaining() faux
 buffer position = 9 limit = 9
buffer clear
 buffer position = 0 limit = 10
 put( "xyz")
 buffer position = 3 limit = 10
flip
 buffer position = 0 limit = 3
essaye get(tableau de 5 char)
Exception in thread "main" java.nio.BufferUnderflowException
        at java.nio.HeapCharBuffer.get(HeapCharBuffer.java:127)
        at java.nio.CharBuffer.get(CharBuffer.java:638)
        at BufferNio4.main(BufferNio4.java:48)

Les lignes de la classe :

les méthodes Put<Type> et get<Type>

Source de BufferNio7.java
import java.io.*;
import java.nio.*;
public class BufferNio7
{
  static public void main( String args[] ) throws Exception {
    ByteBuffer buffer = ByteBuffer.allocate( 100 );
    System.out.println("put un char puis int puis long puis double");
    buffer.putChar('a');
    buffer.putInt(12345);
    buffer.putLong(88000000000L );
    buffer.putDouble(9.8765);
    buffer.flip();
    System.out.println( buffer.getChar() );
    System.out.println( buffer.getInt() );
    System.out.println( buffer.getLong() );
    System.out.println( buffer.getDouble() ); 
    buffer.rewind();
    System.out.println("entier : "+buffer.getInt() );
    System.out.println("char : "+buffer.getChar() );
    for (int i=0; i<50; i++)
       buffer.getDouble();
  }
}

EXECUTION
$java BufferNio7
put un char puis int puis long puis double
a
12345
88000000000
9.8765
entier : 1627390000
char : ?
Exception in thread "main" java.nio.BufferOverflowException
        at java.nio.Buffer.nextPutIndex(Unknown Source)
        at java.nio.HeapByteBuffer.putDouble(Unknown Source)
        at BufferNio7.main(BufferNio7.java:22)

Les lignes de la classe :

adressage absolu et relatif du Buffer

Source de BufferNio8.java
import java.io.*;
import java.nio.*;
public class BufferNio8
{
  static public void main( String args[] ) throws Exception {
    CharBuffer carBuf = CharBuffer.wrap("abcdefghijklmnopqrstuvwxyz");
    System.out.println("wrap : "+carBuf);
    String s = carBuf.toString();
    System.out.println("toString : "+s);
    System.out.println("get(2) : "+(char)(carBuf.get(2)) );
    System.out.println("position() : "+carBuf.position() );
    System.out.println("get() : "+(char)(carBuf.get()) );
    System.out.println("position() : "+carBuf.position() );
    System.out.println("get() : "+(char)(carBuf.get()) );
    System.out.println("position() : "+carBuf.position() );
    System.out.println("charAt(0) : "+carBuf.charAt(0) );
    System.out.println("position() : "+carBuf.position() );
    System.out.println("toString : "+carBuf.toString());
  }
}

EXECUTION
$ java BufferNio8
wrap : abcdefghijklmnopqrstuvwxyz
toString : abcdefghijklmnopqrstuvwxyz
get(2) : c
position() : 0
get() : a
position() : 1
get() : b
position() : 2
charAt(0) : c
position() : 2
toString : cdefghijklmnopqrstuvwxyz

Les lignes de la classe :

 

exercices