从 /dev/input 读取几个字节时出现 IOException
IOException when reading few bytes from /dev/input
尝试从 /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);
按预期读取数据
I would like to figure out why the line is.read(three_bytes);
throws the exception while is.read(twentyfour_bytes);
reads the data as expected.
首先,/dev/input/event16
不是常规文件。它是一个设备文件,而设备文件的行为通常不像普通文件。
在这种情况下,/dev/input/event*
设备文件用于从输入设备读取事件。当您对它们执行 read
系统调用时,它们将 return 一个或多个完整事件。这些是二进制数据,其格式由以下 C struct
:
给出
struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
unsigned int value;
};
不过,在典型的 64 位 Linux 系统上,该结构的大小(大概)是 24 字节。
My initial experiments suggest that the buffer needs capacity for at least one full input_event
struct. But I could not find out why.
事件设备的行为记录在 Linux Input drivers v1.0 的第 5 节中。它指出 read
将始终给出整数个 input_event
结构。
因此,read
系统调用提供了一个小于 sizeof(input_event)
的缓冲区,内核不能 return 任何东西。显然,这会导致 read
系统调用失败,errno 值为 EINVAL
。 (IMO,这是一个合理的设计选择,并且与EINVAL
的文档含义一致。)
因此,在 Java 中,当您调用 read(three_bytes)
时,它将映射到读取大小为 3 字节的 read
系统调用,该调用失败;看上面。系统调用失败通过抛出 IOException
.
向 Java 应用程序发出信号
尝试从 /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);
按预期读取数据
I would like to figure out why the line
is.read(three_bytes);
throws the exception whileis.read(twentyfour_bytes);
reads the data as expected.
首先,/dev/input/event16
不是常规文件。它是一个设备文件,而设备文件的行为通常不像普通文件。
在这种情况下,/dev/input/event*
设备文件用于从输入设备读取事件。当您对它们执行 read
系统调用时,它们将 return 一个或多个完整事件。这些是二进制数据,其格式由以下 C struct
:
struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
unsigned int value;
};
不过,在典型的 64 位 Linux 系统上,该结构的大小(大概)是 24 字节。
My initial experiments suggest that the buffer needs capacity for at least one full
input_event
struct. But I could not find out why.
事件设备的行为记录在 Linux Input drivers v1.0 的第 5 节中。它指出 read
将始终给出整数个 input_event
结构。
因此,read
系统调用提供了一个小于 sizeof(input_event)
的缓冲区,内核不能 return 任何东西。显然,这会导致 read
系统调用失败,errno 值为 EINVAL
。 (IMO,这是一个合理的设计选择,并且与EINVAL
的文档含义一致。)
因此,在 Java 中,当您调用 read(three_bytes)
时,它将映射到读取大小为 3 字节的 read
系统调用,该调用失败;看上面。系统调用失败通过抛出 IOException
.