【问题标题】:Problem: Java-Read socket (Bluetooth) input stream until a string (<!MSG>) is read问题:Java 读取套接字(蓝牙)输入流,直到读取字符串 (<!MSG>)
【发布时间】:2011-05-13 19:41:07
【问题描述】:

我使用以下代码(来自蓝牙聊天示例应用程序)来读取传入数据并根据读取的字节构造一个字符串。我想读到这个字符串到达​​&lt;!MSG&gt;。如何用 read() 函数插入这个条件?

整个字符串看起来像这样&lt;MSG&gt;&lt;N&gt;xxx&lt;!N&gt;&lt;V&gt;yyy&lt;!V&gt;&lt;!MSG&gt;。但是 read() 函数不会一次读取整个字符串。当我显示字符时,我看不到同一行中的所有字符。它看起来像:

发件人:&lt;MS

发件人:G&gt;&lt;N&gt;xx

发件人:x&lt;V

.

.

.

我在手机 (HTC Desire) 上显示字符并使用 Windows 超级终端发送数据。

如何确保所有字符都显示在一行中?我曾尝试使用 StringBuilder 和 StringBuffer 而不是 new String() 但问题是 read() 函数不会读取所有发送的字符。输入流的长度(字节)不等于发送的字符串的实际长度。从读取的字节构造字符串是正常的。

感谢您为此提供的任何建议和时间。如果有的话,也请随时提出其他错误或更好的方法。

干杯,

马杜

public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        //Writer writer = new StringWriter();
        byte[] buffer = new byte[1024];           
        int bytes;
        //String end = "<!MSG>";
        //byte compare = new Byte(Byte.parseByte(end));

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                //boolean result = buffer.equals(compare);
                //while(true)   {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    //Reader reader = new BufferedReader(new InputStreamReader(mmInStream, "UTF-8"));
                    //int n;
                    //while ((bytes = reader.read(buffer)) != -1)   {   
                        //writer.write(buffer, 0, bytes);

                    //StringBuffer sb = new StringBuffer();                    
                    //sb = sb.append(buffer);

                    //String readMsg = writer.toString();
                    String readMsg = new String(buffer, 0, bytes);

                    //if (readMsg.endsWith(end))
                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, readMsg)
                            .sendToTarget();                        
                //}                    

            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

【问题讨论】:

    标签: java conditional inputstream stringbuilder


    【解决方案1】:

    read 函数不保证它返回的字节数(它通常会尝试从流中返回尽可能多的字节,而不会阻塞)。因此,您必须缓冲结果,并将它们放在一边,直到您获得完整的消息。请注意,您可能会在"&lt;!MSG&gt;" 消息之后收到一些东西,因此您必须注意不要将其丢弃。

    您可以尝试以下方法:

    byte[] buffer = new byte[1024];
    int bytes;
    String end = "<!MSG>";
    StringBuilder curMsg = new StringBuilder();
    
    while (-1 != (bytes = mmInStream.read(buffer))) {
        curMsg.append(new String(buffer, 0, bytes, Charset.forName("UTF-8")));
        int endIdx = curMsg.indexOf(end);
        if (endIdx != -1) {
            String fullMessage = curMsg.substring(0, endIdx + end.length());
            curMsg.delete(0, endIdx + end.length());
            // Now send fullMessage
        }
    }
    

    【讨论】:

    • 根据消息大小,在附加之前获取curMsg 大小并从该位置- end.length() - 1 开始查找end 可能是合理的(检查> 0)。
    • 嗨弗拉维奥,非常感谢您的帮助。我能够通过您的建议解决问题并在一行中阅读完整的消息,然后在我的项目中使用该消息进行进一步解析和更多操作。再一次感谢你。干杯
    猜你喜欢
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 2016-07-28
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2012-08-16
    相关资源
    最近更新 更多