Partage de technologie

Alphabétisation complète du modèle de réseau Java

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Aperçu

Décrit les connaissances de base de NIO au niveau ava, pour un examen de base

1. Présentation du NIO

En Java, NIO (Non-blocking I/O ou New I/O) est un nouvel ensemble d'API d'opération d'entrée/sortie introduit dans Java SE 1.4 et les versions ultérieures.

​ Par rapport au modèle IO traditionnel, il offre une plus grande efficacité et de meilleures capacités de traitement simultané. La principale caractéristique de NIO est sa fonctionnalité non bloquante, qui permet à un seul thread de gérer plusieurs canaux d'E/S, améliorant ainsi considérablement les performances des applications dans des scénarios à forte concurrence.

Le scénario d'utilisation de Java NIO est particulièrement adapté aux situations où un grand nombre de connexions simultanées doivent être traitées. Par exemple, dans un serveur réseau, un thread peut gérer des milliers de connexions client sans qu'il soit nécessaire d'allouer un thread indépendant pour chaque connexion. .Peut réduire considérablement la consommation des ressources du système et améliorer les capacités de traitement.

2. Trois composants majeurs de NIO en Java

1. Canaux

Le canal est le support de flux de données dans Java NIO. Il est bidirectionnel et peut être utilisé pour lire ou écrire des données. Le principal avantage des canaux est qu'ils ne sont pas bloquants, ce qui signifie qu'un thread peut gérer plusieurs canaux. Lorsqu'aucun événement ne se produit sur un canal, le thread ne sera pas bloqué et pourra gérer d'autres tâches. Les principaux types de canaux comprennent :

  • FileChannel: Utilisé pour les opérations de lecture et d'écriture de fichiers. Il peut être utilisé pour écrire des données du tampon dans le fichier ou pour lire des données du fichier dans le tampon.
  • SocketChannel: Utilisé pour les connexions TCP dans les communications réseau et peut être utilisé pour lire et écrire des données.
  • ServerSocketChannel: Utilisé pour accepter de nouvelles connexions SocketChannel, similaires au ServerSocket traditionnel.
  • DatagramChannel: Utilisé pour la communication UDP, qui peut envoyer et recevoir des datagrammes.

2. Tampons

​Buffer est un objet utilisé pour stocker des données dans NIO. Il s'agit d'un tableau d'octets qui peut écrire et lire des données. Un tampon a une capacité spécifique et possède deux propriétés importantes : la position et la limite.

  • Capacité: Le nombre maximum d'éléments que le tampon peut stocker.
  • Position: L'index de l'élément en cours d'opération, qui change lorsque les données sont lues ou écrites.
  • Limite: En mode lecture, la valeur maximale que la position peut atteindre ; en mode écriture, la position ne peut pas dépasser la valeur.

Les principaux types de tampons sontByteBufferCharBufferShortBufferIntBufferLongBufferFloatBufferetDoubleBuffer, chaque type correspond à un type de données primitif.

3. Sélecteurs

Un sélecteur est un multiplexeur dans NIO qui permet à un seul thread de surveiller les événements de plusieurs canaux, tels que les événements de lecture, d'écriture, de connexion et de réception. Le sélecteur avertit l'application lorsqu'un des canaux est prêt pour les opérations d'E/S. L'utilisation de sélecteurs améliore considérablement les capacités de traitement simultané des applications réseau car il n'est pas nécessaire de créer un thread pour chaque connexion.

Les principales méthodes de sélection comprennent :

  • select(): Bloque jusqu'à ce qu'au moins un canal soit prêt pour les opérations d'E/S.
  • selectedKeys(): Renvoie un Set contenant les objets SelectionKey de tous les canaux préparés.
  • wakeup(): Interruption bloquéeselect()transfert.

SelectionKeyIl s'agit de l'association entre les sélecteurs et les canaux. Il représente le statut d'enregistrement d'un canal sur le sélecteur, y compris les canaux, les sélecteurs, les collections d'événements intéressées et les collections d'événements prêtes.

3. Programmation réseau

1. Blocage des E/S

​ Il s'agit du modèle d'E/S le plus traditionnel. En Java, les API Socket et ServerSocket traditionnelles sont basées sur le blocage des E/S. Dans ce mode, lorsqu'un thread lance une opération de lecture ou d'écriture, le thread est bloqué jusqu'à ce que l'opération d'E/S soit terminée. S'il n'y a aucune donnée à lire pour l'opération de lecture, ou si l'opération d'écriture ne peut pas être terminée immédiatement, le thread attendra que l'opération soit terminée.

Caractéristiques:

  • Modèle de programmation simple: Facile à comprendre et à mettre en œuvre.
  • Occupation des ressources: Chaque connexion nécessite un thread indépendant, ce qui entraîne un nombre limité de threads et une consommation de ressources élevée.
  • Limites de performances: Dans les scénarios à forte concurrence, le changement de thread et le changement de contexte sont coûteux et peuvent facilement devenir des goulots d'étranglement.

2. E/S non bloquantes

​ Les E/S non bloquantes font partie du framework Java NIO (New I/O), qui permet aux threads de lancer des opérations de lecture et d'écriture sans être bloqués. S'il n'y a aucune donnée à lire pour une opération de lecture, ou si l'opération d'écriture ne peut pas être terminée immédiatement, le thread ne sera pas suspendu et pourra continuer à effectuer d'autres tâches.

Caractéristiques:

  • la flexibilité: Les threads peuvent gérer plus de connexions car ils ne sont pas bloqués en attendant les opérations d'E/S.
  • Complexité accrue: Le programmeur doit vérifier explicitement si l'opération est terminée, ce qui augmente la difficulté de programmation.
  • Amélioration des performances: Dans les scénarios à forte concurrence, la surcharge provoquée par le changement de thread peut être considérablement réduite.

3. Multiplexage

Le multiplexage consiste à surveiller plusieurs descripteurs de fichiers en même temps via un seul thread et à n'opérer sur un descripteur que lorsqu'il est prêt (cela signifie généralement que les données sont lisibles ou que le tampon d'écriture est accessible en écriture). Les sélecteurs sont utilisés en Java pour implémenter le multiplexage.

Caractéristiques:

  • Haute concurrence: Un thread peut gérer des milliers de connexions, améliorant considérablement le débit du serveur.
  • Efficace: Ce n'est que lorsqu'une opération d'E/S est prête que le thread sera réveillé pour éviter une commutation de thread inutile.
  • Économie de ressources: Par rapport au blocage des E/S, les serveurs sous le modèle de multiplexage peuvent utiliser les ressources système plus efficacement.

Avis:

Dans les applications pratiques, les E/S non bloquantes sont souvent utilisées en conjonction avec le multiplexage. Par exemple, un serveur peut utiliser un sélecteur pour surveiller plusieurs SocketChannels. Lorsqu'un SocketChannel contient des données pouvant être lues ou écrites, le sélecteur en informera le serveur et celui-ci traitera ce SocketChannel spécifique de manière non bloquante.

4.NIO VS BIO

4.1 flux vs canal

En Java, Stream et Channel sont deux manières différentes de traiter les flux de données. Ils appartiennent respectivement à la bibliothèque IO standard de Java et à la bibliothèque NIO. Voici une comparaison détaillée des deux concepts :

Flux

Stream fait partie du modèle IO (blocage IO) standard de Java, qui fournit un moyen de lire et d'écrire des données de manière séquentielle. Stream est divisé en deux types : InputStream et OutputStream, qui sont utilisés respectivement pour lire et écrire des données.Ces flux peuvent être des flux d'octets (tels queInputStream, OutputStream) ou un flux de caractères (tel queReader, Writer)。

Caractéristiques:

  • Obstructif: Par défaut, les opérations Stream sont bloquantes, c'est-à-dire que s'il n'y a aucune donnée à lire dans l'opération de lecture ou si l'opération d'écriture ne peut pas être terminée immédiatement, le thread appelant sera bloqué jusqu'à ce que l'opération soit terminée.
  • Unidirectionnalité: Chaque Stream a une direction, soit en lecture seule, soit en écriture seule.
  • arrêt automatique : Après avoir utilisé Stream, vous devez généralement l'appelerclose() méthode pour libérer des ressources.À partir de Java 7, l'instruction try-with-resources peut fermer automatiquement l'implémentationAutoCloseableRessources d’interface, y compris Stream.

Canal

Channel fait partie du modèle Java NIO (New IO), qui offre un niveau d'abstraction plus élevé que Stream, permettant un traitement plus efficace des données. Les canaux peuvent être bidirectionnels, ce qui signifie qu'ils peuvent être utilisés pour lire et écrire des données.Les principaux types de canaux incluentFileChannelSocketChannelServerSocketChanneletDatagramChannel

Caractéristiques:

  • non bloquant :Le canal peut être configuré en mode bloquant ou non bloquant. En mode non bloquant, si une opération de lecture n'a aucune donnée à lire ou si une opération d'écriture ne peut pas être terminée immédiatement, l'opération sera renvoyée immédiatement au lieu de bloquer le thread.
  • Opérations de tampon:Les opérations sur les canaux sont toujours effectuées via le tampon (Buffer). Les données sont lues du canal dans le tampon ou écrites du tampon vers le canal.
  • Multiplexage: Channel peut être utilisé avec Selector pour réaliser le multiplexage, permettant à un thread de surveiller les opérations d'E/S de plusieurs canaux et d'améliorer les capacités de traitement simultanées.

Résumer

  • Scène applicable: Stream est plus adapté au traitement de petits ensembles de données ou d'opérations de fichiers simples, tandis que Channel est plus adapté au traitement de grandes quantités de données, en particulier les communications réseau et les opérations de fichiers volumineux, car il offre des performances plus élevées et de meilleures capacités de concurrence.
  • Complexité de la programmation: L'API de Stream est relativement simple et facile à utiliser ; tandis que les API de Channel et NIO sont plus complexes, mais offrent des fonctions plus puissantes et une plus grande efficacité.
  • La gestion des ressources: Qu'il s'agisse d'un flux ou d'un canal, les ressources doivent être gérées de manière appropriée et garantir qu'elles sont fermées lorsqu'elles ne sont plus nécessaires pour éviter les fuites de ressources.

4.2. Modèle IO

En Java, les modèles d'opération d'E/S peuvent être classés en fonction des deux dimensions synchrone/asynchrone et bloquant/non bloquant.

4.2.1 E/S de blocage synchrone

définition : Le blocage synchrone des E/S est le modèle d'E/S le plus traditionnel lorsqu'un thread appelle une opération d'E/S (telle que la lecture ou l'écriture), le thread sera bloqué jusqu'à ce que l'opération soit terminée. Cela signifie que le thread ne peut effectuer aucune autre tâche tant que l’opération n’est pas terminée.

Caractéristiques

  • Simple et facile à utiliser, la logique du code est claire.
  • Chaque opération d'E/S nécessite un thread exclusif, ce qui n'est pas adapté aux scénarios de concurrence élevée et peut conduire à un épuisement des ressources du thread.
  • Couramment utilisé dansInputStreamOutputStreamSocketetServerSocketscène.

Exemple:

Utiliser le traditionnelInputStreametOutputStreamPour lire et écrire des fichiers :

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SyncBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4.2.2 E/S synchrones non bloquantes

définition : Dans les E/S synchrones non bloquantes, le thread ne sera pas bloqué après l'appel de l'opération d'E/S. Si l'opération ne peut pas être terminée immédiatement, la méthode renverra immédiatement, renvoyant généralement une valeur spéciale (telle que -1 ou 0) ou lançant une exception pour indiquer que l'opération n'est pas terminée.

Caractéristiques

  • L'état de l'opération doit être interrogé jusqu'à ce que l'opération soit terminée.
  • Utilisation des threads plus élevée, car les threads peuvent effectuer d’autres tâches en attendant les E/S.
  • L'implémentation est plus complexe et doit gérer les interrogations et les vérifications de statut.
  • Basé sur Java NIOChannelsetBuffers, en appelantconfigureBlocking(false)Réglez le canal en mode non bloquant.

Exemple:

Utiliser NIOFileChannelPour une lecture et une écriture non bloquantes :

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;

public class SyncNonBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            inChannel.configureBlocking(false);
            while (inChannel.read(buffer) > 0) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4.2.3 E/S de multiplexage synchrone

définition: Utilisation du modèle d'E/S multiplexées synchronesSelector(sélecteur) pour surveiller plusieursChannel événement.Quand le fil appelleSelector.select(), il bloquera jusqu'à ce qu'il y en ait au moins unChannelDes événements (tels que lisible, inscriptible, demande de connexion, etc.) se produisent.

Caractéristiques

  • Permet à un thread de gérer plusieursChannel, améliore la concurrence.
  • passerSelectoretSelectionKeyMécanisme capable de gérer efficacement un grand nombre de connexions simultanées.
  • Convient aux scénarios de serveur réseau, tels que les serveurs Web et les serveurs de discussion.
  • Basé sur le framework Java NIO.

Exemple:

Utiliser NIOFileChannelPour une lecture et une écriture non bloquantes :

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class SyncMultiplexingIOExample {
    public static void main(String[] args) throws IOException {
        try (Selector selector = Selector.open();
             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
            serverSocketChannel.socket().bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                if (selector.select() > 0) {
                    Set<SelectionKey> keys = selector.selectedKeys();
                    for (SelectionKey key : keys) {
                        if (key.isAcceptable()) {
                            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                            SocketChannel clientChannel = ssc.accept();
                            clientChannel.configureBlocking(false);
                            clientChannel.register(selector, SelectionKey.OP_READ);
                        }
                    }
                    keys.clear();
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4.2.4 E/S asynchrones non bloquantes

définition : Dans le modèle d'E/S asynchrone non bloquant, le thread revient immédiatement après le lancement de l'opération d'E/S sans attendre la fin de l'opération. Une fois l'opération terminée, le thread sera averti de manière asynchrone via une fonction de rappel ou une notification d'événement.

Caractéristiques

  • Modèle d'E/S le plus efficace, les threads ne sont pas bloqués du tout et peuvent effectuer d'autres tâches immédiatement.
  • passerAsynchronousChannelInterface et implémentation de sa sous-classe, telle queAsynchronousFileChanneletAsynchronousSocketChannel
  • Convient aux scénarios à haute concurrence et hautes performances, tels que le traitement de Big Data et les serveurs réseau à charge élevée.
  • Java 7 a introduit le modèle d'E/S asynchrone non bloquant.

Exemple:

Utiliser NIOAsynchronousFileChannelEffectuez la lecture et l'écriture de fichiers asynchrones :

import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;

public class AsyncNonBlockingIOExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        AsynchronousFileChannel inChannel = AsynchronousFileChannel.open(Paths.get("input.txt"), StandardOpenOption.READ);
        AsynchronousFileChannel outChannel = AsynchronousFileChannel.open(Paths.get("output.txt"), StandardOpenOption.WRITE);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        CountDownLatch latch = new CountDownLatch(1);
        inChannel.read(buffer, 0, buffer, 0, (channel, result) -> {
            buffer.flip();
            outChannel.write(buffer, 0, buffer, 0, null);
            latch.countDown();
        });
        latch.await();
        inChannel.close();
        outChannel.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Remarque : Le modèle asynchrone nécessite la prise en charge du système d'exploitation sous-jacent (noyau).

  • Les systèmes Windows implémentent de véritables E/S asynchrones via IOCP
  • Les E/S asynchrones dans le système Linux ont été introduites dans la version 2.6, mais son implémentation sous-jacente utilise toujours le multiplexage pour simuler les E/S asynchrones, et il n'y a aucun avantage en termes de performances.

4.2.5 E/S de blocage asynchrone

définition : En théorie, ce modèle n'existe pas, car « asynchrone » signifie que l'opération est effectuée en arrière-plan et que le thread n'est pas bloqué. Par conséquent, le blocage asynchrone des E/S est un concept contradictoire et n'apparaîtra pas dans la pratique.

4.2.6 Résumé

Le choix du modèle d'E/S approprié est essentiel pour la gestion des performances et des ressources. Dans les scénarios à forte concurrence, les modèles d'E/S synchrones non bloquantes ou d'E/S multiplexées synchrones sont des choix courants. Dans les scénarios qui nécessitent des performances et une vitesse de réponse extrêmes, le modèle d'E/S asynchrones non bloquantes est le premier choix.

4.3 Zéro copie

Concept zéro copie

​La technologie zéro copie signifie que pendant le processus de transmission de données d'un endroit à un autre, les données n'ont pas besoin d'être copiées entre l'espace utilisateur et l'espace noyau, ou du moins réduit le nombre de telles copies, améliorant ainsi l'efficacité du système. Dans les opérations d'E/S traditionnelles, lorsque les données sont lues à partir du réseau ou du disque, elles sont d'abord copiées dans le tampon de l'espace noyau, puis copiées de l'espace noyau vers le tampon de l'espace utilisateur. Au contraire, en version zéro copie, les données peuvent être traitées directement dans l'espace du noyau, ou directement transférées de l'espace du noyau vers le périphérique réseau, réduisant ainsi l'opération de copie du processeur, réduisant la surcharge du système et améliorant l'efficacité de la transmission des données.

Source de copie zéro

Le concept de copie zéro est apparu pour la première fois dans la conception des systèmes d'exploitation, dans le but de résoudre les goulots d'étranglement en termes de performances provoqués par la copie de données dans les opérations d'E/S traditionnelles. Dans les premiers systèmes informatiques, toutes les opérations d'E/S nécessitaient plusieurs copies de données dans l'espace utilisateur et dans l'espace noyau. Cela est progressivement devenu un goulot d'étranglement en termes de performances après que les réseaux à haut débit et les disques de grande capacité soient devenus courants.

Points techniques clés

  • E/S directes: permet aux applications d'accéder directement aux périphériques de disque, en ignorant le mécanisme de mise en cache du système de fichiers.
  • Mappage de mémoire (MMAP): Mappez les fichiers en mémoire afin que les données des fichiers soient accessibles comme la mémoire, réduisant ainsi la copie.
  • Envoyer le fichier: Appel système Linux permettant de transférer des données directement d'un descripteur de fichier à un autre, en évitant les copies intermédiaires.
  • DMA (accès direct à la mémoire): Technologie de niveau matériel qui permet aux données d'être transférées directement entre l'appareil et la mémoire sans intervention du processeur.

Implémentation en Java :

Java prend en charge la technologie zéro copie via le framework NIO (New I/O). NIO présentéFileChanneletSocketChannel et d'autres classes, qui fournissent des opérations d'E/S plus efficaces. Spécifiquement,FileChannel.transferTo()etFileChannel.transferFrom()Les méthodes peuvent transférer des données directement d'un canal de fichier vers un canal de socket ou vice versa sans charger les données dans un tampon, obtenant ainsi une copie nulle.

Par exemple, supposons que vous deviez envoyer le contenu d'un fichier volumineux au réseau. L'approche traditionnelle consiste d'abord à lire le contenu du fichier dans un tampon, puis à écrire le contenu du tampon sur le réseau. Cela implique deux opérations de copie : une du disque vers le tampon et une autre du tampon vers le réseau.en utilisanttransferTo()Lorsque vous utilisez cette méthode, les données peuvent être transférées directement du disque vers le réseau sans avoir besoin d'un tampon intermédiaire, ce qui réduit le nombre de copies et atteint zéro copie.

Un exemple utilisant ByteBuffer :

ByteBufferet autreBufferclasse (commeCharBufferShortBufferetc.) fournissent des tampons qui peuvent être remplis ou vidés sans impliquer directement une copie entre l'espace utilisateur et l'espace noyau.ByteBufferPeut être utilisé directement ou indirectement dans la technologie zéro copie :

  1. Tampon directByteBuffer.allocateDirect(size)CrééByteBuffer Les instances sont mappées directement sur la mémoire physique, en contournant le tas Java.Lorsqu'un tel tampon est comparé àFileChannelouSocketChannel Lorsqu'elles sont utilisées ensemble, les données peuvent être transférées directement entre la mémoire physique et les périphériques matériels sans avoir besoin de copies supplémentaires via le tas Java. Cela permet un véritable zéro copie sur certaines plates-formes.
  2. utiliserFileChanneldetransferTo()ettransferFrom(): Ces méthodes permettent de stocker les données directement dansFileChanneletSocketChanneltransmis entreByteBuffer comme intermédiaire. Cela signifie que les données peuvent être transférées directement du disque au réseau ou vice versa sans avoir à les copier entre l'espace utilisateur et l'espace noyau.
  3. utiliserByteBufferdewrap()méthodewrap()La méthode vous permet d'envelopper un tableau d'octets existant ou un autre tampon dans unByteBuffer , il n'est donc pas nécessaire de copier les données dans un nouveau tampon. Ceci est utile pour éviter la copie inutile des données.
  4. utiliserByteBufferdeslice()méthodeslice() La méthode crée une vue du tampon sans copier les données sous-jacentes.Cela signifie qu'un grandByteBufferDivisez en plusieurs tampons plus petits sans copier de données.

Combinez ByteBuffer avec FileChannel :

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class ZeroCopyExample {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            long transferred = fileChannel.transferTo(0, fileChannel.size(), System.out);
            System.out.println("Transferred bytes: " + transferred);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Avis:

Nous devons noter qu'en fait, il n'existe pas de copie zéro complète. La copie zéro mentionnée ici concerne uniquement notre application elle-même, qui n'a pas de copie au niveau utilisateur. Mais même au niveau de l'utilisateur, il est impossible de n'avoir aucune opération de copie, mais de réduire les copies autant que possible. Par conséquent, nous pouvons comprendre que le terme zéro copie fait en réalité référence à la technologie de réduction du nombre de copies de données. et cela ne signifie pas qu'il n'y a pas d'opération de copie fidèle.