所以,我正在从BufferedReader中读取。一切顺利,直到我添加一个条件。我需要从BufferedReader中读取特定的持续时间。
这就是我现在正在做的。
while ((line = br.readLine()) != null
&& System.currentTimeMillis() - start < maxReadTime.toMillis()) {
// doingSomethingHere()
}
问题:即使时间已过,InputStream仍处于活动状态。 例如-maxReadTime是30秒。输入将持续20秒。在接下来的12秒内,没有任何活动。现在,当下一个输入到达时,流将打开并仅在读取输入后关闭。但是,我不处理此输入,因为while循环终止。
我期望或需要的是:流将在30秒后关闭。也就是说,当输入到达第32秒时,流关闭并且不监听任何输入。
我隐约约的ExecutorService知道。我不知道这是去的正确方法。
答案 0 :(得分:1)
只需先设置计时器条件,然后再从流中读取
while ((line = br.readLine()) != null) {
boolean active = System.currentTimeMillis() - start < maxReadTime.toMillis();
if (!active) {
br.close();
}
// doingSomethingHere()
}
在这种情况下,如果第一个条件是false
(时间已到),则第二个条件将根本不会执行
答案 1 :(得分:1)
基本上必须检查如果缓冲器是呼叫readLine()
之前准备通过调用方法ready()
,为InputStream
校验available()
方法,该方法返回如何可能字节可以不用读
这里有个例子
import java.io.*;
import java.time.Duration;
public class Main {
public static void main(String[] args) {
final InputStream in = System.in; //new FileInputStream(new File("/tmp/x"));
final String out = readInput(in, Duration.ofSeconds(5));
System.out.printf("m=main, status=complete, out=%s%n", out);
}
public static String readInput(InputStream in, Duration duration) {
final long timestamp = System.currentTimeMillis();
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
final StringBuilder out = new StringBuilder();
try {
String line = null;
while (true){
if(Duration.ofMillis(System.currentTimeMillis() - timestamp).compareTo(duration) >=0 ){
System.out.println("m=readInput, status=timeout");
break;
}
if(!reader.ready()){
System.out.println("m=readInput, status=not ready");
sleep(1000);
continue;
}
line = reader.readLine();
if(line == null){
System.out.println("m=readInput, status=null line");
break;
}
out.append(line);
out.append('\n');
System.out.printf("m=readInput status=read, line=%s%n" , line);
}
return out.toString();
} catch (IOException e){
throw new RuntimeException(e);
} finally {
System.out.println("m=readInput, status=complete");
}
}
static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {}
}
}
如果你想这样做的背景,你可以按照这个例子
package com.mageddo;
import java.io.*;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
final InputStream in = System.in; //new FileInputStream(new File("/tmp/x"));
final StringBuilder out = new StringBuilder();
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<String> promise = executor.submit(() -> readInput(in, out));
try {
final String result = promise.get(5, TimeUnit.SECONDS);
System.out.printf("m=main, status=success, result=%s%n", result);
} catch (TimeoutException e) {
System.out.println("m=main, status=timeout");
in.close();
promise.cancel(true);
System.out.println("Failed output: " + promise.get());
e.printStackTrace();
} finally {
executor.shutdown();
System.out.println("m=main, status=shutdown, out=" + out);
}
}
public static String readInput(InputStream in, StringBuilder out) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
try {
String line = null;
while (true){
if(Thread.currentThread().isInterrupted()){
System.out.println("m=readInput status=interrupt signal");
break;
}
if(!reader.ready()){
System.out.println("m=readInput, status=not ready");
sleep(1000);
continue;
}
line = reader.readLine();
if(line == null){
System.out.println("m=readInput, status=null line");
break;
}
out.append(line);
out.append('\n');
System.out.printf("m=readInput status=read, line=%s%n" , line);
}
return out.toString();
} catch (IOException e){
throw new RuntimeException(e);
} finally {
System.out.println("m=readInput, status=complete");
}
}
static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}