Maison > Java > javaDidacticiel > Comment implémenter une lecture chronométrée à partir d'un InputStream sans thread ?

Comment implémenter une lecture chronométrée à partir d'un InputStream sans thread ?

Susan Sarandon
Libérer: 2024-12-26 15:54:11
original
887 Les gens l'ont consulté

How to Implement a Timed Read from an InputStream Without Threading?

Lectures chronométrées possibles à partir d'un InputStream

Le défi réside dans la conception d'une méthode appelée MaybeRead qui renvoie le même résultat que in.read() si les données sont disponibles dans un délai spécifié. Plus précisément, MaybeRead renvoie -2 si aucune donnée n'est disponible dans le délai imparti.

Au départ, il semble que l'emballage d'InputStream dans un Reader ou InterruptibleChannel pourrait offrir une solution, mais les deux ne passent que par les méthodes InputStream. De plus, il est essentiel d'éviter toute apparition de thread au cours de ce processus.

Malgré l'opinion selon laquelle in.available() renvoie toujours 0, la documentation révèle qu'elle fournit une estimation des octets disponibles pour la lecture sans blocage. Bien que cette estimation puisse être sous-estimée, elle rattrape l'appel suivant pour prendre en compte les nouveaux arrivants.

Cependant, les sous-classes d'InputStream gèrent leur propre implémentation de available(), et des implémentations concrètes la remplacent pour donner des valeurs significatives. Par conséquent, la simple utilisation de is.available() n'est pas suffisante.

Pour des lectures non bloquantes et sans délai d'attente, envisagez les solutions suivantes :

byte[] inputData = new byte[1024];
int result = is.read(inputData, 0, is.available());  // -1 for EOF with no data read.
Copier après la connexion

Ou

BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("ISO-8859-1")),1024);
// ...
         // inside some iteration / processing logic:
         if (br.ready()) {
             int readCount = br.read(inputData, bufferOffset, inputData.length-bufferOffset);
         }
Copier après la connexion

Pour une solution plus complexe qui maximise le tampon dans un délai d'attente, utilisez la méthode ci-dessous :

public static int readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis)
     throws IOException  {
     int bufferOffset = 0;
     long maxTimeMillis = System.currentTimeMillis() + timeoutMillis;
     while (System.currentTimeMillis() < maxTimeMillis &amp;&amp; bufferOffset < b.length) {
         int readLength = java.lang.Math.min(is.available(),b.length-bufferOffset);
         int readResult = is.read(b, bufferOffset, readLength);
         if (readResult == -1) break;
         bufferOffset += readResult;
     }
     return bufferOffset;
 }
Copier après la connexion

Et utilisez-la comme suit :

byte[] inputData = new byte[1024];
int readCount = readInputStreamWithTimeout(System.in, inputData, 6000);  // 6 second timeout
// readCount indicates bytes read; -1 for EOF with no data read.
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal