簡體   English   中英

從 /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); 按預期讀取數據

我想弄清楚為什么這條線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 輸入驅動程序 v1.0的第 5 節中。它指出read將始終給出整數個input_event結構。

因此, read系統調用提供的緩沖區小於sizeof(input_event) ,kernel 無法返回任何內容。 顯然,這會導致read系統調用以 errno 值EINVAL失敗。 (IMO,這是一個合理的設計選擇,並且與EINVAL的文檔含義一致。)


因此,在 Java 中,當您調用read(three_bytes)時,將 map 到read大小為 3 字節的讀取系統調用失敗; 看上面。 系統調用失敗通過拋出IOException通知給 Java 應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM