【问题标题】:IOException when reading few bytes from /dev/input从 /dev/input 读取几个字节时出现 IOException
【发布时间】:2021-06-16 15:24:51
【问题描述】:

当尝试从/dev/input/event16 读取 input_events 时,我注意到我正在读取的缓冲区的大小可能会导致异常。这是我写的代码:

    public static void main(String[] args) throws IOException{
        FileInputStream is = new FileInputStream("/dev/input/event16");
        byte[] three_bytes = new byte[3];
        byte[] twentyfour_bytes = new byte[24];
        is.read(three_bytes); // fails
        is.read(twentyfour_bytes); // does not fail

    }

我最初的实验表明缓冲区需要至少一个完整的input_event 结构的容量。但我找不到原因。

问题是is.read(three_bytes); 行导致以下异常:

Exception in thread "main" java.io.IOException: Invalid argument
        at java.base/java.io.FileInputStream.readBytes(Native Method)
        at java.base/java.io.FileInputStream.read(FileInputStream.java:249)
        at main.Test.main(Test.java:11)

我想弄清楚为什么 is.read(three_bytes); 行会抛出异常,而is.read(twentyfour_bytes); 会按预期读取数据

【问题讨论】:

  • 我不确定我是否理解正确。您想以编程方式获取/dev/input/event16 的大小吗?
  • 不,我尝试读取文件的内容
  • 我仍然不清楚你会发现什么。看来你可以用 24 字节数组读取文件,为什么不直接使用更大的数组呢?
  • 我很好奇为什么我需要更大的数组。

标签: java linux-device-driver inputstream input-devices


【解决方案1】:

我想弄清楚为什么is.read(three_bytes); 行会抛出异常,而is.read(twentyfour_bytes); 会按预期读取数据。

首先,/dev/input/event16 不是常规文件。它是一个设备文件,而且设备文件的行为通常不像常规文件。

在这种情况下,/dev/input/event* 设备文件用于从输入设备读取事件。当您对它们执行read 系统调用时,它们将返回一个或多个完整事件。这些是二进制数据,其格式由以下 C struct 给出:

struct input_event {    
    struct timeval time;    
    unsigned short type;
    unsigned short code;
    unsigned int value; 
};

不过,在典型的 64 位 Linux 系统上,该结构的大小(大概)是 24 字节。

我最初的实验表明缓冲区需要至少一个完整的input_event 结构的容量。但我找不到原因。

事件设备的行为记录在Linux Input drivers v1.0,第 5 节。它指出read 将始终提供整数个input_event 结构。

因此read 系统调用提供的缓冲区小于sizeof(input_event),内核无法返回任何内容。显然,这会导致read 系统调用失败,错误号为EINVAL。 (IMO,这是一个合理的设计选择,并且与 EINVAL 的文档含义一致。)


因此,在 Java 中,当您调用 read(three_bytes) 时,它将映射到读取大小为 3 字节的 read 系统调用,但失败;看上面。系统调用失败通过抛出IOException 向Java 应用程序发出信号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 2014-09-20
    • 1970-01-01
    • 2015-03-05
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多