write a string to a serial port in java - java

i want to write a string to a serial port, but serial port write method allows only byte array to write in it...so how can i send whole string to a port..here is my code...
serialPort.setSerialPortParams(300,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
OutputStream mOutputToPort = serialPort.getOutputStream();
String mValue = "ABCDEFG";
System.out.println("beginning to Write . \r\n");
mOutputToPort.write(mValue.getBytes());
System.out.println("AT Command Written to Port. \r\n");
mOutputToPort.flush();
i dont want to send it one by one char..i want whole at a time... thnxx in advance

Your code works (it does write the whole string at once), but it is not nice. If this is what you intend to do, the "clean" way to do it is:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(mOutputToPort));
bw.write(mValue);
// probably "write" some more here to the buffer
bw.flush(); // now ensure accumulated data is actually written
If you are only writing one string and not more you might as well use an OutputStreamWriter directly and not use a buffer:
OutputStreamWriter osw = new OutputStreamWriter(mOutputToPort);
osw.write(mValue, 0, mValue.length());
osw.flush();
(In Java, Writers deal with writing characters to streams instead of bytes.)
If you want to ensure that no buffering occurs (and I doubt there is any reason for it, it will only increase system call overhead since the serial port will buffer the data anyway and send it out slower than your code delivers it), 123456789 provided a suitable answer. You should be careful with calling getBytes() though, as this will use the system's default character encoding (usually UTF-8 or ISO-8859-1, both suitable for writing pure ASCII) to convert from characters to bytes. If you want a particular encoding then specify it in the call to getBytes(), e.g.
try {
byte[] bytes = someString.getBytes("US-ASCII");
for (int i=0; i<bytes.length; i++)
mOutputToPort.write(bytes[i]); }
catch (UnsupportedEncodingException e) {} // well, this one is always supported

Try to use getBytes() method which returns byte array.
OutputStream mOutputToPort = serialPort.getOutputStream();
String mValue = "ABCDEFG";
System.out.println("beginning to Write . \r\n");
Byte[] data = mValue.getBytes();
for(int i=0;i<data.length;i++){
mOutputToPort.write(data[i]);}
System.out.println("AT Command Written to Port. \r\n");
mOutputToPort.flush();

Related

write hex string as bytes to socket java

I have a string of hex values that I am trying to write to a socket as bytes.
String confDeliv = "\\x7E\\x01\\x00\\x20\\x37\\x02\\x03\\xF2\\xD5";
I have tried doing this to try and solve my problem
byte [] Delivery_Conf = {(byte)0x7E, (byte)0x01, (byte)0x00, (byte)0x20,
(byte)0x37, (byte)0x02, (byte)0x03, (byte)0xF2, (byte)0xD5};
But I have yet to succeed to write it to the socket. I don't get any errors but when I send it to the device it doesn't do what I need it to do I have tried two different ways of doing this.
Try 1:
DataOutputStream dOut = new DataOutputStream(sock.getOutputStream()); //69.171.154.64
for (int i = 0; i < Delivery_Conf.length-1; i++) {
dOut.writeByte(Delivery_Conf[i]);
}
dOut.flush();
This method I used when I but the values into a byte array.
Try 2:
DataOutputStream dOut = new DataOutputStream(sock.getOutputStream());
dOut.writeBytes(confDeliv);
dOut.flush();
This is the method I used when I tried sending it as the string but still no luck. I am able to make the device work when I use python using its byte string.
eg.
confDel = b"\x7E\x01\x00\x20\x37\x02\x03\xF2\xD5"
I think java changes something when I send it and I think that is why I can get it to work with java. I have looked around for while but I do not seem to find anything that will help me with my problem.
You should use the following:
byte [] Delivery_Conf = {(byte)0x7E, (byte)0x01, (byte)0x00, (byte)0x20,
(byte)0x37, (byte)0x02, (byte)0x03, (byte)0xF2, (byte)0xD5};
// ...
dos.write(Delivery_conf);
The version you had writing a byte at a time should work but it's inefficient, and it's possible that the device has timing constraints.
The version using the String isn't correct. Adding another backslash to make \x compile is not a correct solution: you should change \x to \u00 throughout. Throughout the string, that is, of course.

Compare DataOutputStream to String in Java

I have a DataOutputStream I would like to copy into a string. I've found a lot of tutorials on converting DataOutputStreams by setting it to a new ByteArrayOutputStream, but I just want to read the string it sends when it flushes, and my DataOutputStream is already assigned to an output stream though a socket.
output.writeUTF(input.readLine());
output.flush();
If the context is helpful, I'm trying to read the output stream of a server and compare it to a string.
the flush method will flush, i.e. force write, anything buffered, but not yet written.
In the code below, try putting a breakpoint on the second call to writeUTF - if you navigate to your file system you should see the created file, and it will contain "some string". If you put the break point on flush, you can verify that the content has already been written to file.
public static void test() throws IOException {
File file = new File("/Users/Hervian/tmp/fileWithstrings.txt");
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream(file));
dos.writeUTF("some string");
dos.writeUTF("some other string");
dos.flush();//Flushes this data output stream. This forces any buffered output bytes to be written out to the stream.
} finally {
if (dos!=null) dos.close();
}
}
As such, you cannot extract the data from the DataOutputStream object, but in the example above we off course have those strings in the write calls.

Not working I/O method

I'm pretty new to JAVA, so I do not really see what I am doing wrong within the following method:
public void writeWNDFile(){
String strFilePath = "C:/Users/fperrone/Desktop/ddd.txt";
try
{
//create FileOutputStream object
FileOutputStream fos = new FileOutputStream(strFilePath);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeDouble(12);
dos.close();
}
catch (IOException e)
{
System.out.println("IOException : " + e);
}
}
The file is actually generated, but I don't get 12 as printed and expected result, but #(, which probably is the ASCII representation.
May you shed some light?
EDIT
Does eventually exist a JAVA function behaving similarly to the MATLAB fwrite function? I actually wanna write a binary file. In MATLAB I am simply calling:
fwrite(filename, A, precision)
How could I achieve the same in JAVA?
DataOutputStream.writeDouble and other methods of DataOutputStream are designed to write numbers in binary format. If you want your data be saved in text format use FileWriter and its write(String) method. You can convert double to String with Double.toString(double).
from writeDouble java docs:
Converts the double argument to a long using the doubleToLongBits
method in class Double, and then writes that long value to the
underlying output stream as an 8-byte quantity, high byte first.
As DataOutputStream uses the binary format to write, hence you are seeing the same. But you need to worry if you are going to read the file again using DataInputStream and readDouble method. It should give you the right values.
//PrintWriter out = new PrintWriter(new BufferedWriter(
// new OuputStreamWriter(new FileOutputStream(strFilePath) /*, "UTF-8"*/)));
PrintWriter out = new PrintWriter(strFilePath /*, "UTF-8"*/);
out.println(12);
out.close();
Add the encoding, here UTF-8, when you want the application to write with the same encoding everywhere. Otherwise the default platform encoding is used.
PrintWriter's println adds a newline, print not.

DataInputStream and readLine() with UTF8

I've got some trouble with sending a UTF8 string from a c socket to a java socket.
The following method works fine:
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
main.title = in.readLine();
but then I need a int java.io.InputStream.read(byte[] b, int offset, int length) method which does not exist for a BufferedReader. So then I tried to take a DataInputStream
DataInputStream in2 = new DataInputStream(socket.getInputStream());
but everything it reads is just rubbish.
Then I tried to use the readLine() method from DataInputStream but this doesn't give me the correct UTF8 string.
You see my dilemma. Can't I use two readers for one InputStream? Or can I convert the DataInputStream.readLine() result and convert it to UTF8?
Thanks,
Martin
We know from the design of the UTF-8 encoding that the only usage of the value 0x0A is the LINE FEED ('\n'). Therefore, you can read until you hit it:
/** Reads UTF-8 character data; lines are terminated with '\n' */
public static String readLine(InputStream in) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while (true) {
int b = in.read();
if (b < 0) {
throw new IOException("Data truncated");
}
if (b == 0x0A) {
break;
}
buffer.write(b);
}
return new String(buffer.toByteArray(), "UTF-8");
}
I am making the assumption that your protocol uses \n as a line terminator. If it doesn't - well, it is generally useful to point out the constraints you're writing to.
Do NOT use BufferedReader and DataInputStream on the same InputStream!! I did that and spent days trying to figure out why my code broke. BufferedReader can read more than what you extract from it into its buffer, resulting in situation when the data I was supposed to read with the DataInputStream being "in the BufferedReader". This resulted in lost data which caused my program to "hang" waiting for it to arrive.
I believe that you should not mismatch the BufferedReader and DataInputStream here. DataInputStream has readLine() too, so use it.
And yet another comment. I am not sure it is a problem but avoid multiple calls of socket.getInputStream(). Do it once and then wrap it as you want using other streams and readers.
Am I understanding it correctly that you are sending both text and binary data on the same socket, in the same "conversation"? There should be no problem creating two readers for the same inputstream. The problem is knowing when (and how much) to read which reader. They will both consume (and advance) the underlying stream when you read from them, since you have mixed types of data. You could just read the stream as bytes and then convert the bytes explicitly in your code (new String(bytes, "UTF-8") etc). Or you could split your communication onto two different sockets.

how to transfer the records in rms(j2me) to j2se through bluetooth

NOW here is the coding for j2me mobile for sending the string:
String s="hai";
try{
String url = "btspp://001F81000250:1;authenticate=false;encrypt=false;master=false";
StreamConnection stream = null;
InputStream in;
OutputStream out;
stream = (StreamConnection) Connector.open(url);
out=stream.openOutputStream();
String s=tf.getString();
byte size=(byte) s.length();
out.write(size);
out.write(s.getBytes());
out.flush();
out.close();
stream.close();
}
catch(Exception e){
}
NOW the coding for j2se for receiving the String :
StreamConnectionNotifier notifier=null;
try{
String url = "btspp://localhost:"+new UUID("1101", true).toString()+";name=PCServerCOMM;authenticate=false";
System.out.println(LocalDevice.getLocalDevice().getBluetoothAddress()+"\nCreate server by uri: " + url);
notifier= (StreamConnectionNotifier) Connector.open(url);
while(true){
System.out.println("waiting....");
StreamConnection con = notifier.acceptAndOpen();
System.out.println("Got connection..");
InputStream is=con.openInputStream();
//byte b[]=new byte[40];
/*
while(is.available()>0){
System.out.print((char)is.read());
}*/
//is.read(b, 0, 40);
int size=is.read();
byte b[]=new byte[size];
is.read(b, 0, size);
File f=new File("d://test.xml");
FileOutputStream fo=new FileOutputStream(f);
fo.write(b,0,b.length);
fo.close();
con.close();
System.out.println(new String (b));
}
//printing(f);
} catch(Exception e){
JOptionPane.showConfirmDialog(new JFrame(), e.getMessage());
}
I tried this coding for data transfer but it is not a successful one because when the string which we sent is too long then there is problem in receiving side. How can I solve this?
Is there any other way to transfer the data in rms to j2se, if so please help me.... please make your reply quick...
The way you are writing and reading here, only strings up to 255 characters in length, which additionally only take the same number of bytes in your default encoding, are written right.
On the writing side:
The statement byte size=(byte) s.length(); converts the length of the string in a byte, thus only takes the lower 8 bits of the length. So, only lengths up to 255 are written right.
Then you are converting the String to a byte array with s.getBytes() - this array could be longer (in bytes) than the original string in characters. This conversion uses the default encoding of your sending device.
On the reading side:
The statement int size=is.read(); reads the length written before, then you are creating a byte array.
is.read(b, 0, size); reads some bytes into this array - it does not necessarily fills the complete array.
Then you are converting your byte array (which may not even be filled completely) to a string, using the default encoding of the receiving device.
So, we have:
All strings longer than 255 characters are written wrongly.
If sending and receiving side are using different encodings, you may get a wrong output.
If the sending side uses an encoding like UTF-8 where some characters take more than one byte, the string is cut off at the end (if such characters occur).
How to solve this:
If you can use a DataInputStream and DataOutputStream on both sides (I don't know anything about J2ME), use them there, with their readUTF and writeUTF methods. They solve all your problems (if your strings take at most 65535 bytes in the modified UTF-8 encoding used here).
If not:
make a decision on how long the strings can be, and encode your length with the right number of bytes. 4 bytes are enough for every Java String.
measure the length after converting to a byte[], not before.
use a loop for reading into the array, to be sure to capture the whole string.
for the getBytes() and new String(...), use the variants which take an explicit encoding name and give them the same encoding (I recommend "UTF-8").

Categories