[英]java serial read() is waiting indefinitely - how to break it?
我有一个连接到我的PI的串行设备,可以从中读取数据...一切都很好,但是有时电缆移动了或串行设备拔出了。
然后
line = r.readLine();
卡住了
我已尝试通过以下方法解决此问题:
BufferedReader r = new BufferedReader (newnputStreamReader(p.getInputStream()));
try
{
line = r.readLine();
if (line.length() == 0)
{
logfile.append("problem");
logfile.close();
System.out.println("Problem");
TimeUnit.SECONDS.sleep(5);
break;
}
}
catch (IOException e)
{
logfile.append(line);
logfile.close();
}
但是它什么也不做(因为我怀疑他仍在等待数据)甚至都不会引发异常,我该如何让他说我有问题? 也许使用计时器或类似的东西? 如果5秒钟没有数据?
谢谢 ,
在这种情况下,您的假设是正确的。 BufferedReader
的readLine()
方法具有一个内部while-loop
,该while-loop
将从底层输入流中检索所有字节,并且仅在到达的字符为\\n
或\\r
时才会中断。
可以这样想:
while(lastChar != '\n' || lastChar != '\r')
{
//read from stream
}
但是,一旦输入该方法将不会返回。 唯一的例外是这两个特殊字符的出现或InputStream被关闭(在这种情况下,返回null
ist)。
诀窍是在从InputStream读取某些内容之前,不要输入:
public static void main( String[] args ) throws IOException
{
boolean awaitInput = true;
while(awaitInput)
{
if(System.in.available() != 0)
{
awaitInput = false;
// read logic
}
}
}
这只是许多可能的解决方案之一,我以System.in为例,因为它也像其他任何输入源一样都是InputStream。 但是,还有一个称为BufferedReader#ready
的方法,如果有需要读取的内容,则返回true
:
public static void main( String[] args ) throws IOException
{
BufferedReader br = new BufferedReader( new InputStreamReader(System.in) );
boolean awaitInput = true;
while(awaitInput)
{
if(br.ready())
{
awaitInput = false;
String line = br.readLine();
// read logic
}
}
}
最后,如果您想超时,可以这样轻松地自己完成:
public static void main( String[] args ) throws IOException
{
BufferedReader br = new BufferedReader( new InputStreamReader(System.in) );
boolean awaitInput = true;
long timeout = System.currentTimeMillis() + 5_000;
// ^^^^^ 5_000ms = 5 sec
while(awaitInput && System.currentTimeMillis() < timeout)
{
if(br.ready())
{
awaitInput = false;
String line = br.readLine();
// read logic
}
}
}
您可以使用CompletableFuture
并发读取并可以使用超时。
// wrap the readLine into a concurrent call
CompletableFuture<String> lineFuture = CompletableFuture.supplyAsync(() -> r.readLine());
try {
// do the call, but with a timeout
String readLine = lineFuture.get(5, TimeUnit.SECONDS);
// do stuff with the line you read
} catch (TimeoutException e) {
// plug pulled?
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.