Dans Java 7, AsynchronousFileChannel a été ajouté à Java NIO. Utilisez AsynchronousFileChannel pour lire et écrire des données de fichier de manière asynchrone.
Créer un AsynchronousFileChannel
Nous pouvons le créer en utilisant la méthode statique open () fournie par AsynchronousFileChannel. L'exemple de code est le suivant:
Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.READ);
Le premier paramètre est une instance d'objet de PATH, qui pointe vers le fichier associé à AsynchronousFileChannel.
Le deuxième paramètre est une ou plusieurs options d'opération, qui déterminent quelle opération AsynchronousFileChannel effectuera sur le fichier cible. Dans l'exemple de code, nous avons utilisé StandardOpenOption.READ, qui indique que nous allons lire le fichier cible.
Lire les données
AsynchronousFileChannel fournit deux façons de lire des données, toutes deux en appelant sa propre méthode read (). Deux méthodes seront présentées ci-dessous.
La première façon d'utiliser Futrue pour lire des données est d'appeler la méthode read () d'AsynchronousFileChannel, qui retourne un objet de type Future.
Future operation = fileChannelread(buffer, 0);
Le premier paramètre est ByteBuffer. Les données lues à partir d'AsynchronousFileChannel sont d'abord écrites dans ce ByteBuffer.
Le deuxième paramètre indique la position de départ de la lecture des données du fichier.
Cette méthode read () retournera immédiatement, même si tout le processus de lecture n'est pas complètement terminé. Nous pouvons utiliser operation.isDone () pour vérifier si la lecture est terminée. L'opération ici est une instance du type Future retournée par la méthode read () ci-dessus. Voici un exemple de code détaillé:
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
Future<Integer> operation = fileChannel.read(buffer, position);
while(!operation.isDone());
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println(new String(data));
buffer.clear();
Le programme ci-dessus crée d'abord un objet AsynchronousFileChannel, puis appelle sa méthode read () pour renvoyer un Future. La méthode read () nécessite deux paramètres, l'un est ByteBuffer et l'autre est la position de départ de la lecture du fichier. Ensuite, la méthode isDone () est appelée dans une boucle pour vérifier si le processus de lecture est terminé, et la méthode isDone () retournera true après la fin. Bien que cela permette au processeur de rester inactif pendant un certain temps, nous devons attendre la fin de l'opération de lecture avant de passer aux étapes suivantes.
Une fois la lecture terminée, les données sont stockées dans le ByteBuffer, puis les données sont converties en chaîne et en sortie.
Utilisez CompletionHandler pour lire les données
La deuxième façon de lire les données consiste à appeler une autre méthode read () surchargée d'AsynchronousFileChannel, qui nécessite un CompletionHandler comme paramètre. Voici un exemple de code:
fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("result = " + result);
attachment.flip();
byte[] data = new byte[attachment.limit()];
attachment.get(data);
System.out.println(new String(data));
attachment.clear();
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
}
});
Une fois l'opération de lecture terminée, la méthode complete () du CompletionHandler sera appelée. Son premier paramètre est un type Integer, qui représente le nombre d'octets lus. La deuxième pièce jointe de paramètre est de type ByteBuffer et est utilisée pour stocker les données lues. C'est en fait le troisième paramètre de la méthode read (). Dans l'exemple actuel, nous utilisons ByteBuffer pour stocker des données, mais nous pouvons également utiliser d'autres types.
Lorsque la lecture échoue, la méthode failed () de CompletionHandler sera appelée.
L'écriture de données est comme la lecture. Nous avons également deux façons d'écrire des données dans AsynchronousFileChannel. Nous pouvons appeler ses deux méthodes write () surchargées. Nous les présenterons séparément ci-dessous.
Utilisez Future pour lire les données
AsynchronousFileChannel也可以异步写入数据。下面是一个完整的写入示例:
Path path = Paths.get("data/test-write.txt");
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
buffer.put("test data".getBytes());
buffer.flip();
Future<Integer> operation = fileChannel.write(buffer, position);
buffer.clear();
while(!operation.isDone());
System.out.println("Write done");
Commencez par instancier un AsynchronousFileChannel en mode écriture, puis créez un ByteBuffer et écrivez des données. Ensuite, écrivez les données dans le fichier. Enfin, vérifiez le Future retourné pour voir si l'écriture est terminée.
Notez que le fichier cible d'écriture doit être créé à l'avance, s'il n'existe pas, la méthode writh () lèvera une exception java.nio.file.NoSuchFileException.
Nous pouvons résoudre ce problème des manières suivantes:
if(!Files.exists(path)){
Files.createFile(path);
}
Utilisez CompletionHandler pour écrire des données
Nous pouvons également utiliser CompletionHandler au lieu de Future pour écrire des données dans AsynchronousFileChannel. De cette façon, nous pouvons savoir plus directement si le processus d'écriture est terminé. Voici un exemple de programme:
Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
Files.createFile(path);
}
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
buffer.put("test data".getBytes());
buffer.flip();
fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("bytes written: " + result);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("Write failed");
exc.printStackTrace();
}
});
Lorsque la procédure d'écriture est terminée, la méthode completed () du CompletionHandler sera appelée. Au contraire, si l'écriture échoue, la méthode failed () sera appelée.
Faites attention à la façon dont le paramètre attachmentnt de la méthode CompletionHandler est utilisé.
Enfin
Répondez aux données par message privé pour recevoir un résumé des questions d'entretien Java d'un grand fabricant + manuel Alibaba Taishan + un guide d'apprentissage des points de connaissances + un résumé des points de connaissances de base Java dans un document pdf de 300 pages!
Le contenu de ces documents sont tous les points de connaissances que l'intervieweur doit poser pendant l'entretien. Le chapitre comprend de nombreux points de connaissances, y compris les connaissances de base, les collections Java, JVM, la concurrence multithread, les principes de printemps, les microservices, Netty et RPC, Kafka , Agenda, modèle de conception, algorithme Java, base de données, gardien de zoo, cache distribué, structure de données, etc.