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.
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); }
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 && 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; }
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.
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!