Why does my InputStream hold old values?

孤者浪人 提交于 2020-01-06 02:46:06

问题


I am sending an IR signal to the IR receiver which is passed through the BT module to the InputStream of the Android application. Every time I press a button on the emitter, I send 100 bytes which then I expect to get into the InputStream (is there a way to handle an exception when there is no 100 bytes because the packet got corrupted?).

This is my code for reading InputStream and putting values into the byte[] buffer:

 public int read(final InputStream input, final byte[] buffer) throws IOException {
        int remaining = buffer.length;
        try {
            Thread.sleep(100); // Not sure if this helps anything, just a desperate move
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while (remaining > 0) {
            final int location = buffer.length - remaining;
            final int count = input.read(buffer, location, remaining);
            if (count == -1) { // EOF
                break;
            }
            remaining -= count;
        }
        return buffer.length - remaining;
    }

It works fine for couple of times, but at some point, usually after 4th try, I am getting those mentioned bytes without the first byte. It seems like package has been corrupted at some point and only 99 bytes were sent and then subsequently the next sending of the bytes, result in putting one byte to the previous buffer and losing the first byte.

However interesting is, that packets have always 100 bytes, and they are not dummy (zero values) in there.

Those values are accelerometer coordinates (doesn't really matter).

Example correct values:

0 = 1
1 = 35
2 = 0
3 = -27
4 = 19
5 = -4
6 = 64
7 = 10
8 = -7
9 = 66
10 = 10
11 = 0
12 = 66
13 = 4
14 = -1
15 = 64
16 = 8
17 = -1
18 = 67
19 = 7
20 = -3
21 = 66
22 = 6
23 = -1
24 = 65
25 = 7
26 = -2
27 = 66
28 = 7
29 = -3
30 = 65
31 = 6
32 = -3
33 = 67
34 = 6
35 = -2
36 = 66
37 = 7
38 = -2
39 = 66
40 = 4
41 = -3
42 = 66
43 = 6
44 = -3
45 = 66
46 = 6
47 = -3
48 = 66
49 = 5
50 = -3
51 = 66
52 = 6
53 = -2
54 = 65
55 = 5
56 = -3
57 = 65
58 = 6
59 = -3
60 = 66
61 = 6
62 = -3
63 = 66
64 = 6
65 = -3
66 = 66
67 = 6
68 = -2
69 = 66
70 = 5
71 = -3
72 = 66
73 = 5
74 = -3
75 = 66
76 = 5
77 = -2
78 = 66
79 = 5
80 = -3
81 = 66
82 = 5
83 = -3
84 = 66
85 = 6
86 = -2
87 = 66
88 = 5
89 = -2
90 = 65
91 = 5
92 = -2
93 = 65
94 = 5
95 = -2
96 = 66
97 = 4
98 = -2
99 = 66

Example incorrect values (it can also happen that first byte is missing, however in this case there is one more byte at the beginning):

0 = 66
1 = 1
2 = 35
3 = 3
4 = 10
5 = -14
6 = -17
7 = 81
8 = 15
9 = -5
10 = 64
11 = 14
12 = -4
13 = 68
14 = 7
15 = -5
16 = 69
17 = 9
18 = -5
19 = 78
20 = 15
21 = -3
22 = 77
23 = 16
24 = -2
25 = 72
26 = 20
27 = 3
28 = 64
29 = 20
30 = 8
31 = 55
32 = 22
33 = 16
34 = 50
35 = 22
36 = 19
37 = 52
38 = 11
39 = 13
40 = 50
41 = 6
42 = 14
43 = 50
44 = 9
45 = 13
46 = 54
47 = 12
48 = 9
49 = 63
50 = 16
51 = 12
52 = 67
53 = 6
54 = 0
55 = 74
56 = 8
57 = -4
58 = 75
59 = 13
60 = -2
61 = 68
62 = 17
63 = -5
64 = 79
65 = 8
66 = -8
67 = 62
68 = 15
69 = -8
70 = 65
71 = 13
72 = -7
73 = 67
74 = 8
75 = -6
76 = 66
77 = 9
78 = -3
79 = 67
80 = 8
81 = -4
82 = 66
83 = 7
84 = -4
85 = 65
86 = 8
87 = -4
88 = 67
89 = 7
90 = -4
91 = 66
92 = 7
93 = -3
94 = 67
95 = 6
96 = -4
97 = 66
98 = 6
99 = -3

Any idea how to solve it? Note, I don't send 2 packages of bytes twice in less than 3 seconds, if that helps in finding a solution.


回答1:


InputStream is a very low level API, you almost never want to use it directly. In this case, the wrapper that is most suited to your purposes is DataInputStream, which has a readFully method that seems to be what you want; the code is much simpler and shorter.

public void read(final InputStream input, final byte[] buffer) throws IOException, EOFException {
  DataInputStream dataStream = new DataInputStream(input);
  dataStream.readFully(buffer, 0, buffer.length);
}

If this doesn't work, then I suspect the problem is something with the data stream from the IR itself.


If you need to read from the stream with a timeout (in the case of a corrupted packet), then this method is not advised, because it will block, as you've already noticed. In such a case, I recommend reading the information in this question: Is it possible to read from a InputStream with a timeout?



来源:https://stackoverflow.com/questions/32288524/why-does-my-inputstream-hold-old-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!