devstory

Le Tutoriel de Java WritableByteChannel

  1. WritableByteChannel
  2. Methods
  3. write(ByteBuffer src)
  4. Example 1

1. WritableByteChannel

Si vous débutez avec Java NIO, il est utile de lire tout d'abord les articles suivants pour mieux comprendre les bases :
  • Java Nio
WritableByteChannel est une interface qui s'étend à partir de l'interface Channel, qui représente les canaux pouvant écrire des bytes sur un périphérique IO.
public interface WritableByteChannel extends Channel
Par rapport à l'interface parent, WritableByteChannel ne fournit qu'une méthode supplémentaire pour écrire des bytes à partir d'un ByteBuffer vers ce Channel.
public int write(ByteBuffer src) throws IOException;
Une seule opération d'écriture sur le Channel peut avoir lieu à la fois. Cela signifie que si un thread initie une opération d'écriture sur un Channel, les autres threads ne peuvent pas écrire sur ce canal, ils sont bloqués jusqu'à ce que l'opération soit terminée. D'autres opérations d'E/S peuvent être effectuées en même temps que l'opération d'écriture en fonction du type de canal.
La hiérarchie des interfaces et des classes liées à WritableByteChannel :

2. Methods

WritableByteChannel ne fournit qu'une méthode de plus que son interface parente.
public int write(ByteBuffer src) throws IOException;
D'autres méthodes héritent de l'interface Channel :
public boolean isOpen();  
public void close() throws IOException;

3. write(ByteBuffer src)

public int write(ByteBuffer byteBuffer) throws IOException;
La méthode write(ByteBuffer) écrit une séquence de bytes entre la position et la limite-1 sur le ByteBuffer spécifié dans ce Channel. Il écrira autant que possible et renverra le nombre de bytes écrits.
  • Chaque byte écrit sur ce Channel augmentera la position du curseur sur le ByteBuffer de 1.
  • Avant de convoquer cette méthode, il faut au préalable convoquer la méthode ByteBuffer.clear() pour définir la position = 0 et la limit =capacity.
  • Le nombre maximal de bytes pouvant être écrits dans une convocation de cette méthode est byteBuffer.limit()-byteBuffer.position().
La méthode tentera d'écrire tous les bytes de la position à la limite-1 dans ce Channel. Cependant, certains types de Channel(s) tels que SocketChannel, en fonction de leur état, peuvent n'avoir que quelques bytes écrits. Il est nécessaire d'écrire le code comme ci-dessous pour s'assurer que tous les bytes sont écrits avec succès :
while(byteBuffer.hasRemaining())  {
    channel.write(byteBuffer);
}
Une seule opération d'écriture sur le Channel peut avoir lieu à la fois. Cela signifie que si un thread initie une opération d'écriture sur un Channel, les autres threads ne peuvent pas écrire sur ce canal, ils sont bloqués jusqu'à ce que l'opération soit terminée. D'autres opérations d'E/S peuvent être effectuées en même temps que l'opération d'écriture en fonction du type de canal.

4. Example 1

Par exemple : Utiliser WritableByteChannel pour écrire des données dans un fichier.
WritableByteChannel_ex1.java
package org.o7planning.writablebytechannel.ex;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;

public class WritableByteChannel_ex1 {
    // Windows: "C:/somepath/out-file.txt";
    private static final String outFilePath = "/Volumes/Data/test/out-file.txt";

    public static void main(String[] args) throws IOException {  
        OutputStream outputStream = null;
        WritableByteChannel channel = null;
        try {
            byte[] byteData = "JP日本-八洲".getBytes("UTF-8");
            
            File outFile = new File(outFilePath);
            outFile.getParentFile().mkdirs(); // Make sure parent folder is exists.
            outputStream = new FileOutputStream(outFile);
            
            // Create WritableByteChannel to write data to an OutputStream.
            channel = Channels.newChannel(outputStream);
            
            ByteBuffer buffer = ByteBuffer.allocate(byteData.length);
            buffer.put(byteData);
            // Set limit = current position and position = 0;
            buffer.flip();
            
            while(buffer.hasRemaining())  {
                channel.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeQuietly(outputStream);
            closeQuietly(channel);
        }
    }

    private static void closeQuietly(Closeable closeable) {
        try {
            closeable.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
OutputStream et Channel implémentent ou étendent à partir de l'interface Closeable, il a donc la possibilité de se fermer automatiquement si vous utilisez la syntaxe "Closeable-try-catch". Et nous réécrivons l'exemple ci-dessus plus court.
WritableByteChannel_ex1b.java
package org.o7planning.writablebytechannel.ex;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;

public class WritableByteChannel_ex1b {
    // Windows: "C:/somepath/out-file.txt";
    private static final String outFilePath = "/Volumes/Data/test/out-file.txt";

    public static void main(String[] args) throws IOException {
        File outFile = new File(outFilePath);
        outFile.getParentFile().mkdirs(); // Make sure parent folder is exists.

        // Closeable-try-catch Syntax:
        try (OutputStream outputStream = new FileOutputStream(outFile);
                // Create WritableByteChannel to write data to an OutputStream.
                WritableByteChannel channel = Channels.newChannel(outputStream);) { // try

            byte[] byteData = "JP日本-八洲".getBytes("UTF-8");
            ByteBuffer buffer = ByteBuffer.allocate(byteData.length);
            buffer.put(byteData);
            // Set limit = current position and position = 0;
            buffer.flip();

            while (buffer.hasRemaining()) {
                channel.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • Le Tutoriel de Java Closeable