Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I perform an encoding-independent string-comparison in Java?

I'm having a strange problem comparing strings. I send a string to my server (as bytes using getBytes()) from the client. I've ensured that encoding is the same on the client and server by starting both of them with -Dfile.encoding=UTF-8.

I noticed the problem when I was trying to perform a valueOf on the string I receive from the client, to convert it into an enum. When I print out the strings, they look exactly the same. But when I perform a compareTo, I get a non-zero number and equals returns false.

I'm assuming that it is an encoding problem. I'm not really sure though -- I'm still a bit of a novice when it comes to client-server programming with sockets.

This is what I get:

Waiting for connections on port 9090
Connected to client: 127.0.0.1
received command: GetAllItems
The value is |GetAllItems| (from client)
The value is |GetAllItems| (from enum)
equals: false

What am I doing wrong?

UPDATE

Here is how I'm reconstituting the string from the stream. Perhaps this is where I'm doing something wrong?

byte[] commandBytes = new byte[1024];
in.read(commandBytes); //in is a BufferedInputReader
String command = new String(commandBytes);
like image 817
Vivin Paliath Avatar asked Jan 21 '23 08:01

Vivin Paliath


2 Answers

My guess is that since your buffer is bigger than your string, there are added nulls in the reconsituted string. It is legal for nulls to be embedded inside strings in Java (unlike C and company), although Java handles them differently than standard UTF-8.

Try recording the length read, and pass that length to the string constructor:

int bytesRead = in.read(commandBytes);
String command = new String(commandBytes, 0, bytesRead);
like image 116
Tim Yates Avatar answered Feb 02 '23 09:02

Tim Yates


Your problem is in how you are constructing the string. You are reading in the bytes into a buffer length 1024, but you are not telling the String constructor to only look at the relevant points. So your code should be...

byte[] commandBytes = new byte[1024];
int length = in.read(commandBytes); //in is a BufferedInputReader
String command = new String(commandBytes, 0, length);
like image 37
Rob Di Marco Avatar answered Feb 02 '23 08:02

Rob Di Marco