首页 > 解决方案 > 从 Java RandomAccessFile 读取时如何设置超时

问题描述

我正在用 Java 写入和读取 Linux 文件,它实际上是硬件设备的通信端口。为此,我使用了 RandomAccessFile(稍后我会解释原因),它在大多数情况下都能正常工作。但有时会丢失一个字节,然后我的例程会无限期地阻塞,因为读取方法没有超时。

提供有关该文件的更多详细信息:它是一个 USB 收据打印机,它创建一个名为 /dev/usb/lp0 的文件,虽然我可以使用 cups 驱动程序进行打印,但我仍然需要通过该文件进行低级通信来查询打印机的状态。

我使用 RandomAccessFile 的原因是我可以使用相同的对象进行读写。我尝试使用 InputStream 和 OutputStream 制作一个版本(因为这将允许我使用 available() 方法来实现我的超时)。但是,当我第一次打开 InputStream 然后打开 OutputStream 时,由于文件被占用,打开 OutputStream 时出现异常。

我尝试使用 OutputStream 进行写入,然后在打开 InputStream 进行读取之前将其关闭,但是在打开 InputStream 之前我丢失了部分或全部回复。

我尝试改用频道(Files.newByteChannel())。这也允许我只有一个对象,并且文档说它只读取可用字节并返回计数(这也允许我实现超时)。但是不管文档怎么说,当没有什么可读的时候,它仍然会阻塞在 read 方法中。

我还尝试了多种方法来使用线程在 RandomAccessFile 上实现超时。第一种方法是在开始读取的同时启动一个单独的线程,如果线程超时,我从线程关闭文件,希望这会解锁 read() 操作并出现异常,但它没有(它一直被阻止)。我还尝试在单独的线程中进行读取,并在时间过去后使用已弃用的 Thread.stop() 残酷地杀死它。这工作了一次,但此后无法再次重新打开文件。

我所做的唯一解决方案是有一个单独的线程持续调用读取,并且每当它获得一个字节时,它就会将它放入一个 LinkedBlockingQueue,我可以通过超时读取它。这种方法有效,但缺点是我永远无法关闭文件(再次出于上面解释的相同原因,我无法解除阻塞的读取)。我的应用程序要求我有时关闭与硬件的连接。

任何人都可以想到一种在我的情况下可以使用超时的文件读取的方法(这允许我同时对文件进行读取和写入访问)?

顺便说一句,我正在使用Java8。

标签: javalinuxfiletimeout

解决方案


推荐阅读