为什么 InputStreamReader 给我 U-FFFD?我该如何解决?
Why does InputStreamReader giving me U-FFFD? How can I fix it?
我正在尝试从蓝牙设备接收数据,预计格式如下:
00 FE 80 01 01 A0 0A B0 0B C0 0C D0 0D E0 0E F0 0F 00 01 02 03 04 05 06 07 08 09
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25
26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41
42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D
5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 FF FF 68 FF
我希望接收后转换为十进制,应该是这样的:
0 254 128 1 1 160 10 176 11 192 12 208 13 224 14 240 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
109 110 111 112 113 255 255 104 255
然而,我实际收到的是这种形式:
�����F���t?���������������������������������������������
然后如果我尝试将其转换为十六进制:
FFFD FFFD FFFD FFFD FFFD 46 06 FFFD FFFD FFFD 01 74 3F FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
如果是十进制,我会得到这些:
65533 65533 65533 65533 65533 70 6 65533 65533 65533 1 116 63 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533
这是使用 InputStreamReader 和 BufferedReader 读取数据的代码部分(我从这个 library 获得):
override fun openMessageStream(): Flowable<String> {
checkNotClosed()
return Flowable.create({ emitter ->
val reader = BufferedReader(InputStreamReader(inputStream, charset))
while (!emitter.isCancelled && !closed.get()) {
synchronized(inputStream) {
try {
val receivedString = reader.readLine()
if (!TextUtils.isEmpty(receivedString)) {
emitter.onNext(receivedString)
}
} catch (e: Exception) {
if (!emitter.isCancelled && !closed.get()) {
emitter.onError(e)
}
}
}
}
emitter.onComplete()
}, BackpressureStrategy.BUFFER)
}
我尝试了其他建议来更改 InputStreamReader 中使用的字符集。我已经尝试了列出的所有字符集 in this documentation 但仍然没有解决问题。
如何正确读取数据?在处理来自流 reader 的传入数据时,我应该更改哪一部分?
编辑:
我现在可以使用下面的代码并按照 Andy 的建议接收正确的值。现在我可以继续扫描开始位和结束位并获取两者之间的数据。我知道这段代码效率不高,我是 Java 的新手,所以我非常感谢任何改进这段代码的建议。
override fun openMessageStream(): Flowable<String> {
checkNotClosed()
return Flowable.create({ emitter ->
val reader = BufferedInputStream(inputStream)
while (!emitter.isCancelled && !closed.get()) {
synchronized(inputStream) {
try {
val receivedString = reader.read()
if (!TextUtils.isEmpty(receivedString.toString())) {
emitter.onNext(receivedString.toString())
}
} catch (e: Exception) {
if (!emitter.isCancelled && !closed.get()) {
emitter.onError(e)
}
}
}
}
emitter.onComplete()
}, BackpressureStrategy.BUFFER)
}
您似乎没有在读取 二进制 数据,但您正试图将其读取为特定字符集中的字符串。
FFFD 是一个替换字符,基本上是说“无法在此字符集中解释输入数据”。
以二进制形式读取它。不要使用 InputStreamReader
,而是将 InputStream
包装在 BufferedInputStream
中,然后一次读取一个块的字节。
您似乎想要 return String
,但是:我无法评论您应该做什么,或者如果您真正需要的话,如何将您的字节放入字符串中。
我正在尝试从蓝牙设备接收数据,预计格式如下:
00 FE 80 01 01 A0 0A B0 0B C0 0C D0 0D E0 0E F0 0F 00 01 02 03 04 05 06 07 08 09
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25
26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41
42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D
5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 FF FF 68 FF
我希望接收后转换为十进制,应该是这样的:
0 254 128 1 1 160 10 176 11 192 12 208 13 224 14 240 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
109 110 111 112 113 255 255 104 255
然而,我实际收到的是这种形式:
�����F���t?���������������������������������������������
然后如果我尝试将其转换为十六进制:
FFFD FFFD FFFD FFFD FFFD 46 06 FFFD FFFD FFFD 01 74 3F FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
如果是十进制,我会得到这些:
65533 65533 65533 65533 65533 70 6 65533 65533 65533 1 116 63 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533
这是使用 InputStreamReader 和 BufferedReader 读取数据的代码部分(我从这个 library 获得):
override fun openMessageStream(): Flowable<String> {
checkNotClosed()
return Flowable.create({ emitter ->
val reader = BufferedReader(InputStreamReader(inputStream, charset))
while (!emitter.isCancelled && !closed.get()) {
synchronized(inputStream) {
try {
val receivedString = reader.readLine()
if (!TextUtils.isEmpty(receivedString)) {
emitter.onNext(receivedString)
}
} catch (e: Exception) {
if (!emitter.isCancelled && !closed.get()) {
emitter.onError(e)
}
}
}
}
emitter.onComplete()
}, BackpressureStrategy.BUFFER)
}
我尝试了其他建议来更改 InputStreamReader 中使用的字符集。我已经尝试了列出的所有字符集 in this documentation 但仍然没有解决问题。
如何正确读取数据?在处理来自流 reader 的传入数据时,我应该更改哪一部分?
编辑:
我现在可以使用下面的代码并按照 Andy 的建议接收正确的值。现在我可以继续扫描开始位和结束位并获取两者之间的数据。我知道这段代码效率不高,我是 Java 的新手,所以我非常感谢任何改进这段代码的建议。
override fun openMessageStream(): Flowable<String> {
checkNotClosed()
return Flowable.create({ emitter ->
val reader = BufferedInputStream(inputStream)
while (!emitter.isCancelled && !closed.get()) {
synchronized(inputStream) {
try {
val receivedString = reader.read()
if (!TextUtils.isEmpty(receivedString.toString())) {
emitter.onNext(receivedString.toString())
}
} catch (e: Exception) {
if (!emitter.isCancelled && !closed.get()) {
emitter.onError(e)
}
}
}
}
emitter.onComplete()
}, BackpressureStrategy.BUFFER)
}
您似乎没有在读取 二进制 数据,但您正试图将其读取为特定字符集中的字符串。
FFFD 是一个替换字符,基本上是说“无法在此字符集中解释输入数据”。
以二进制形式读取它。不要使用 InputStreamReader
,而是将 InputStream
包装在 BufferedInputStream
中,然后一次读取一个块的字节。
您似乎想要 return String
,但是:我无法评论您应该做什么,或者如果您真正需要的话,如何将您的字节放入字符串中。