【问题标题】:How to convert byte[] to String correctly?如何正确将 byte[] 转换为 String?
【发布时间】:2012-04-30 05:09:15
【问题描述】:

我正在用 Java 构建一个 swing 接口,我构建了一个 middleware,它不断读取串行端口并保存即将发送到 String 的内容,这就是我的做法:

public class RFID {
  private static RFIDReader rReader;
  private static boolean state;

  public RFID(RFIDReader rReader) {
    this.rReader = rReader;
    this.state = true;
  }

  public void connect(String portName) throws Exception {
    CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
    if (portIdentifier.isCurrentlyOwned()) {
        System.out.println("Error: Port is currently in use");
    } else {
        CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);

        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

            InputStream in = serialPort.getInputStream();
            OutputStream out = serialPort.getOutputStream();

            (new Thread(new SerialReader(in))).start();
            //(new Thread(new SerialWriter(out))).start();

        } else {
            System.out.println("Error: Only serial ports are handled by this example.");
        }
    }
}

public static class SerialReader implements Runnable {

    InputStream in;

    public SerialReader(InputStream in) {
        this.in = in;
    }

    public void run() {
        byte[] buffer = new byte[1024];
        int len = -1;
        String code;
        try {
            while (state == true && (len = this.in.read(buffer)) > -1) {
                code = new String(buffer, 0, len);
                if (code.length() > 1)
                    rReader.setCode(code);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void finish(){
    state = false;
}

public static class SerialWriter implements Runnable {

    OutputStream out;

    public SerialWriter(OutputStream out) {
        this.out = out;
    }

    public void run() {
        try {
            int c = 0;
            while ((c = System.in.read()) > -1) {
                this.out.write(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

所以当我尝试打印 code 存储的内容时,它显示如下:

AC000F9
3
BB

实际上应该是这样的:

AC000F93BB

我在这里做错了什么?这个byte[]String的转换不对吧?

编辑: 我需要读取一个总共 10 个字符的字符串。

【问题讨论】:

  • 在 'code' 组合的那一行放置一个断点。读取 len 的值。
  • ..或者,换句话说,为什么它看起来像'AC000F93BB'?为什么 read() 在获得前 7 个字符后不返回?

标签: java string byte type-conversion


【解决方案1】:

不要使用 InputStream 来读取 - 使用某种描述的 Reader。如果您需要InputStream 开头,请将其包装在InputStreamReader 中。不过,我会更改您的构造函数以接受Reader,并允许客户端传递他们想要的任何阅读器。这将使测试更容易(因为您可以只使用StringReader)。

编辑:注意 - 如果您确实需要从二进制 InputStream 创建阅读器,请明确选择 Charset(编码)。所以使用指定一个的InputStreamReader 构造函数重载。即使您想使用平台默认值,我也会明确说明您在做什么。

编辑:除了“字符串转换发生的位置”之外,还不清楚您期望阅读的内容。您正在处理流式 API - 是什么决定了在调用 setCode 之前您真正想阅读多少内容?是一整条线吗?它是一些固定数量的字符吗?是特定分隔符之前的字符吗?

编辑:现在我们知道得更多了,我建议你写一个这样的辅助方法:

// Assuming you now have a field of type Reader, called reader
private String readEntry() throws IOException {
    char[] buffer = new char[10];
    int index = 0;
    while (index < buffer.length) {
        int charsRead = reader.read(buffer, index, buffer.length - index);
        if (charsRead == -1) {
            throw new IOException("Couldn't read entry - end of data");
        }
        index += charsRead;
    }
    return new String(buffer);
}

【讨论】:

  • 我还要补充一点:选择Charset。这是确保您在byte[]String 之间进行转换的唯一方法。
  • @JonSkeet,感谢您的帮助。我是 Java 新手,所以我放了我的课,所以你们可以看看它到底发生了什么。我期望读取一个总共有 10 个字符的字符串。它是固定数量的字符,总是 10 个,没有特定的分隔符,SERIAL_PORT 库已经解决了这个问题,但这只是我们在这里讨论的这个烦人的问题。
  • @ValterHenrique:好的,如果您总是想读取 10 个字符,则需要循环读取“数量”,直到获得 10 个字符。将进行编辑。
  • @ValterHenrique:现在看看。
  • @JonSkeet 我仍然不知道如何初始化reader,因为我需要从InputStream 开始,因为serialPort 对象只有serialPort.getInputStream(),它返回@987654340 @。所以我尝试用InputStreamReader 包装,但这个类不会返回Reader 对象强硬。
猜你喜欢
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 2023-03-10
  • 2021-10-21
  • 2012-05-18
  • 1970-01-01
相关资源
最近更新 更多