2012-04-18 2 views
1

Я строй интерфейса swing в Java, я строй 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 не является правильным?

EDIT: Мне нужно прочитать строку с общим количеством символов 10 символов.

+0

Поставьте точку останова на строке, в которой собран «код». Прочтите значение len. –

+1

..или, другими словами, почему он должен выглядеть как «AC000F93BB»? Почему read() не должен возвращаться после того, как он получил первые 7 символов? –

ответ

5

Не используйте InputStream для чтения - используйте Reader некоторого описания. Если вам нужен, чтобы начать с InputStream, оберните его в InputStreamReader. Я бы сменил ваш конструктор, чтобы принять Reader, и разрешить клиентам передавать любой читатель, в котором они хотят. Это облегчит тестирование (поскольку вы можете просто использовать StringReader).

EDIT: Обратите внимание - если вы сделать необходимость создания чтения из двоичного InputStream, быть явным в выборе Charset (кодирования). Поэтому используйте переопределение конструктора InputStreamReader, который указывает его. Даже если вы хотите использовать платформу по умолчанию, я буду откровенен в этом, чтобы дать понять, что вы делаете.

EDIT: Помимо «где происходит преобразование строки», неясно, что вы ожидаете прочитать. Вы имеете дело с потоковыми API-интерфейсами - что определяет, сколько вы действительно хотите прочитать перед вызовом setCode? Это целая линия? Это некоторое фиксированное количество символов? Это символы перед конкретным разделителем?

EDIT: Теперь мы знаем немного больше, я предлагаю вам написать вспомогательный метод как это:

// 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); 
} 
+1

Я бы также добавил: * выберите 'Charset' *. Это единственный способ убедиться в вашем преобразовании между 'byte []' и 'String'. –

+0

@LouisWasserman: Да, сделает это явным. –

+0

@JonSkeet, спасибо за вашу помощь. Я новичок в Java, поэтому я поставил свой класс, чтобы вы, ребята, могли посмотреть, что это на самом деле происходит. Я ожидаю прочитать строку с 10 символами в общей сложности. Это фиксированное количество символов, всегда 10, нет специального разделителя, библиотека 'SERIAL_PORT' уже позаботится об этом, но это только эта неприятная проблема, которую мы обсуждаем здесь. –

Смежные вопросы