Reputation: 16656
I'm building a swing
interface in Java, I build a middleware
which keeps reading the serial port and saving what's coming to String
, here it's how I'm doing this:
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();
}
}
}
So when I try to print what code
is storing, it shows like this:
AC000F9
3
BB
What actually should look like this:
AC000F93BB
What am I doing wrong here ? This conversion from byte[]
to String
is not right ?
EDIT: I need to read a string with 10 characters at total.
Upvotes: 1
Views: 1515
Reputation: 1499880
Don't use an InputStream
to read from - use a Reader
of some description. If you need to start with an InputStream
, wrap it in an InputStreamReader
. I would change your constructor to accept a Reader
though, and allow clients to pass whatever reader they want in. That will make it easier to test (as you can just use a StringReader
).
EDIT: Note - if you do need to create a reader from a binary InputStream
, be explicit in your choice of Charset
(encoding). So use the InputStreamReader
constructor overload which specifies one. Even if you want to use the platform default, I'd be explicit about that to make it clear what you're doing.
EDIT: Beyond "where the string conversion happens" it's unclear what you're expecting to read. You're dealing with streaming APIs - what determines how much you really want to read before calling setCode
? Is it a whole line? Is it some fixed number of characters? Is it characters before a particular delimiter?
EDIT: Now we know a bit more, I suggest you write a helper method like this:
// 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);
}
Upvotes: 5