codestory

Die Anleitung zu Java WritableByteChannel

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

1. WritableByteChannel

Wenn Sie gerade erst mit Java NIO beginnen, lesen Sie zuerst die folgenden Artikel, um mehr über die Grundlagen zu erfahren:
  • Java Nio
WritableByteChannel ist eine Interface, die sich von der Interface Channel erstreckt, die Kanäle darstellt, die bytes in ein IO-Gerät schreiben können.
public interface WritableByteChannel extends Channel
Im Vergleich zur übergeordneten Interface bietet WritableByteChannel nur eine weitere Methode, um bytes aus einem ByteBuffer in diesen Channel zu schreiben.
public int write(ByteBuffer src) throws IOException;
Es kann jeweils nur eine Schreiboperation auf dem Channel stattfinden. Das bedeutet, dass, wenn ein Thread eine Schreiboperation auf einem Channel einleitet, andere Threads nicht auf diesem Channel schreiben können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ Channel können andere Operationen IO gleichzeitig mit der Schreiboperation ausgeführt werden.
Hierarchie der Interface und Klassen im Zusammenhang mit WritableByteChannel:

2. Methods

WritableByteChannel bietet nur eine Methode mehr als die übergeordnete Interface.
public int write(ByteBuffer src) throws IOException;
Andere Methoden erben von der Interface Channel:
public boolean isOpen();  
public void close() throws IOException;

3. write(ByteBuffer src)

public int write(ByteBuffer byteBuffer) throws IOException;
Die Methode write(ByteBuffer) schreibt eine Folge von bytes zwischen position und limit-1 auf dem angegebenen ByteBuffer in diesen Channel. Es wird so viel wie möglich schreiben und die Anzahl der geschriebenen bytes zurückgeben.
  • Jedes in diesen Channel geschriebene byte erhöht die Cursorposition auf dem ByteBuffer um 1.
  • Bevor Sie diese Methode aufrufen, sollten Sie die Methode ByteBuffer.clear() aufrufen, um position = 0 und limit = capacity zu setzen.
  • Die maximale Anzahl von bytes, die in einem Aufruf dieser Methode geschrieben werden können, ist byteBuffer.limit()-byteBuffer.position().
Die Methode versucht, alle bytes von position bis limit-1 in diesen Channel zu schreiben. Bei einigen Typen Channel wie SocketChannel können jedoch je nach Status nur wenige bytes geschrieben werden. Sie müssen also folgenden Code schreiben, um sicherzustellen, dass alle bytes erfolgreich geschrieben wurden:
while(byteBuffer.hasRemaining())  {
    channel.write(byteBuffer);
}
Es kann jeweils nur eine Schreiboperation auf dem Channel stattfinden. Das bedeutet, dass, wenn ein Thread eine Schreiboperation auf einem Channel einleitet, andere Threads nicht auf diesem Channel schreiben können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ Channel können andere Operationen IO gleichzeitig mit der Schreiboperation ausgeführt werden.

4. Example 1

Beispiel: Verwenden Sie WritableByteChannel, um Daten in eine Datei zu schreiben.
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();
        }
    }
}
Sowohl OutputStream als auch Channel implementieren oder erweitern die Interface Closeable, sodass sie automatisch geschlossen werden kann, wenn Sie die Syntax "Closeable-try-catch" verwenden. Und wir schreiben das obige Beispiel kürzer um.
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();
        }
    }
}
  • Die Anleitung zu Java Closeable