Kotlin的readBytes()永远不会完成

4

我只是想通过蓝牙套接字进行写入和读取,但我的readBytes调用没有完成。我认为这非常简单,但也许我只是使用了错误类型的流或其他东西。就目前而言,我的代码只是将少量文本作为字节发送。这是占位符代码,将被用写入和读取文件的代码所替换。以下是我的接收线程:

class ReceiveThread(val inStream:BufferedInputStream):Thread() {

var bytes:ByteArray? = null


override fun run() {
    BluetoothService.log("Begin ${BTS_Constants.THREAD_RECEIVE}")
    BluetoothService.log("preparing to read data")
    name = BTS_Constants.THREAD_RECEIVE

//here is my new code
    inStream.use {
        do{
            count++
            BluetoothService.log("read loop round $count")
            byteList.add(it.read() as Byte)
        }while (it.available()>0)
     }
    BluetoothService.log("data read: ${byteList.get(0) as Char}")
}
}

这是我的“发送线程”:

class SendThread(val outStream:BufferedOutputStream, val file:File? = null):Thread(){

var bytes:ByteArray? = null

override fun run() {
    BluetoothService.log("Begin : ${BTS_Constants.THREAD_SEND}")
    name = BTS_Constants.THREAD_SEND

    bytes = "hello testing".toByteArray()
    try{
        outStream.use {
            it.write(bytes)
            it.flush()
        }
    }catch (ioe:IOException){

    }

    BluetoothService.log("data sent")
}

}

数据成功发送,BluetoothService.log("data sent") 被调用并在运行Send线程的设备的logcat中显示。对于运行Receive线程的设备,日志记录了“准备读取数据”的消息,但从未记录 data read: "$bytes message"
我该如何使调用inStream.readBytes()完成?
编辑:我收到了一个新的错误消息:
11-27 23:45:29.298 16253-16413/com.example.zemcd.fileblue E/AndroidRuntime: FATAL EXCEPTION: RECEIVE
                                                                        Process: com.example.zemcd.fileblue, PID: 16253
                                                                        java.io.IOException: bt socket closed, read return: -1
                  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:588)
                  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
                  at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
                  at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
                  at com.example.zemcd.fileblue.ReceiveThread.run(BluetoothService.kt:230)
1个回答

2
如果您查看Kotlin扩展函数readBytes的源代码,您会发现它在InputStream.read(buffer) > 0的循环中开始执行。根据文档:

该方法会一直阻塞,直到有输入数据可用、检测到文件结束或抛出异常。

此循环的第二次迭代将会冻结您的程序。因此,请不要使用方法readBytes,而是使用read(buffer)方法。例如:https://developer.android.com/guide/topics/connectivity/bluetooth.html#ManagingAConnection 更新:
现在ReceiveThread可以从流中接收一个消息。但是您的蓝牙套接字已关闭。所以您的问题可能在于设置蓝牙连接和初始化inStream时出现了错误。也许您的发送部分也有问题。

谢谢。这个答案非常有用,但我已经对代码进行了更改,但仍然被阻塞。也许我误解了。我将bytes = it.readBytes()更改为byteSize = it.read(buffer)并在我的接收线程中添加了一个byteSize变量,作为Int字段。我需要做更多的事情吗?我在文档中没有看到更多内容,并且因为我正在使用Kotlin,所以无法执行while((byteSize = it.read(buffer))!=-1)循环。 - Mox_z
@Mox_z 你确定 ReceiveThread 调用 read 方法之前 SendThread 调用 write 方法吗? - Dmitrii Nechepurenko
是的,写入端正在完成发送。但是这可能与它是BufferedInputStream有关吗?那里使用了不同的技术吗? - Mox_z
@Mox_z 为什么你不能使用 while?这可能是蓝牙连接问题吗? - Dmitrii Nechepurenko
我猜在 Kotlin 中,我向你展示的例子是一个赋值语句,不能用作 while(expression) 期望作为参数的表达式的替代品。也许有一种解决方法?我会尝试查看我的发送代码,也许我只是漏掉了某些东西。此外,我将发布一个编辑版本的问题,显示更新后的代码和新的错误消息。我认为这有助于澄清我的问题。 - Mox_z
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接