I am converting a String to byte[] and then again byte[] to String in java using the getbytes() and String constructor,
String message = "Hello World";
byte[] message1 = message.getbytes();
using PipedInput/OutputStream I send this to another thread, where,
byte[] getit = new byte[1000];
pipedinputstream.read(getit);
print(new String(getit));
This last print result in 1000 to be printed... I want the actual string length. How can i do that?
When reading the String, you need to get the number of bytes read, and give the length to your String:
byte[] getit = new byte[1000];
int readed = pipedinputstream.read(getit);
print(new String(getit, 0, readed));
Note that if your String is longer than 1000 bytes, it will be truncated.
You are ignoring the number of bytes read. Do it as below:
byte[] getit = new byte[1000];
int bytesRead = pipedinputstream.read(getit);
print(new String(getit, 0, bytesRead).length());
public String getText (byte[] arr)
{
StringBuilder sb = new StringBuilder (arr.length);
for (byte b: arr)
if (b != 32)
sb.append ((char) b);
return sb.toString ();
}
not so clean, but should work.
I am converting a String to byte[] and then again byte[] to String
Why? The round trip is guaranteed not to work. String is not a container for binary data. Don't do this. Stop beating your head against the wall: the pain will stop after a while.
Related
I am trying the following:
C# Client:
string stringToSend = "Hello man";
BinaryWriter writer = new BinaryWriter(mClientSocket.GetStream(),Encoding.UTF8);
//write number of bytes:
byte[] headerBytes = BitConverter.GetBytes(stringToSend.Length);
mClientSocket.GetStream().Write(headerBytes, 0, headerBytes.Length);
//write text:
byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(stringToSend);
writer.Write(textBytes, 0, textBytes.Length);
Java Server:
Charset utf8 = Charset.forName("UTF-8");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), utf8));
while (true) {
//we read header first
int headerSize = in.read();
int bytesRead = 0;
char[] input = new char[headerSize];
while (bytesRead < headerSize)
{
bytesRead += in.read(input, bytesRead, headerSize - bytesRead);
}
String resString = new String(input);
System.out.println(resString);
if (resString.equals("!$$$")) {
break;
}
}
The string size equals 9.That's correct on both sides.But, when I am reading the string iteself on the Java side, the data looks wrong.The char buffer ('input' variable)content looks like this:
",",",'H','e','l','l','o',''
I tried to change endianness with reversing the byte array.Also tried changing string encoding format between ASCII and UTF-8.I still feel like it relates to the endianness problem,but can not figure out how to solve it.I know I can use other types of writers in order to write text data to the steam,but I am trying using raw byte arrays for the sake of learning.
These
byte[] headerBytes = BitConverter.GetBytes(stringToSend.Length);
are 4 bytes. And they aren't character data so it makes no sense to read them with a BufferedReader. Just read the bytes directly.
byte[] headerBytes = new byte[4];
// shortcut, make sure 4 bytes were actually read
in.read(headerBytes);
Now extract your text's length and allocate enough space for it
int length = ByteBuffer.wrap(headerBytes).getInt();
byte[] textBytes = new byte[length];
Then read the text
int remaining = length;
int offset = 0;
while (remaining > 0) {
int count = in.read(textBytes, offset, remaining);
if (-1 == count) {
// deal with it
break;
}
remaining -= count;
offset += count;
}
Now decode it as UTF-8
String text = new String(textBytes, StandardCharsets.UTF_8);
and you are done.
Endianness will have to match for those first 4 bytes. One way of ensuring that is to use "network order" (big-endian). So:
C# Client
byte[] headerBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(stringToSend.Length));
Java Server
int length = ByteBuffer.wrap(headerBytes).order(ByteOrder.BIG_ENDIAN).getInt();
At first glance it appears you have a problem with your indexes.
You C# code is sending an integer converted to 4 bytes.
But you Java Code is only reading a single byte as the length of the string.
The next 3 bytes sent from C# are going to the three zero bytes from your string length.
You Java code is reading those 3 zero bytes and converting them to empty characters which represent the first 3 empty characters of your input[] array.
C# Client:
string stringToSend = "Hello man";
BinaryWriter writer = new BinaryWriter(mClientSocket.GetStream(),Encoding.UTF8);
//write number of bytes: Original line was sending the entire string here. Optionally if you string is longer than 255 characters, you'll need to send another data type, perhaps an integer converted to 4 bytes.
byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(stringToSend);
mClientSocket.GetStream().Write((byte)textBytes.Length);
//write text the entire buffer
writer.Write(textBytes, 0, textBytes.Length);
Java Server:
Charset utf8 = Charset.forName("UTF-8");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), utf8));
while (true) {
//we read header first
// original code was sending an integer as 4 bytes but was only reading a single char here.
int headerSize = in.read();// read a single byte from the input
int bytesRead = 0;
char[] input = new char[headerSize];
// no need foe a while statement here:
bytesRead = in.read(input, 0, headerSize);
// if you are going to use a while statement, then in each loop
// you should be processing the input but because it will get overwritten on the next read.
String resString = new String(input, utf8);
System.out.println(resString);
if (resString.equals("!$$$")) {
break;
}
}
I have a ByteArrayOutputStream which holds a byte representation of an XML with 750MB size.
I need to convert it to String.
I wrote:
ByteArrayOutputStream xmlArchive = ...
String xmlAsString = xmlArchive.toString(UTF8);
However although I am using 4GB of heap size I get java.lang.OutOfMemoryError: Java heap space
What is wrong? How can I know which heap size to use? I am using JDK64 bit
UPDATE
I need it as String in order to remove all the characters before "<?xml"
Currently my code is:
String xmlAsString = xmlArchive.toString(UTF8);
int xmlBegin = xmlAsString.indexOf("<?xml");
if (xmlBegin >0){
return xmlAsString.substring(xmlBegin);
}
return xmlAsString;
I then convert it again to byte array.
UPDATED 2
The ByteArrayOutputStream is written like this:
HttpMethod method ..
InputStream response = method.getResponseBodyAsStream();
byte[] buf = new byte[5000];
while ( (len=response.read(buf)) != -1) {
output.write(buf, 0, len);
}
len is from the header of the response Content-Length
You could use the Scanner class:
Scanner scanner = new Scanner(response, StandardCharsets.UTF_8.name());
// skip to "<?xml"
scanner.skip(".*?(?=<\\?xml)");
// process rest of stream
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// Do something with line
}
scanner.close();
Expanding on Jamie Cockburn's answer:
To fill in his while loop to match your expected behaviour:
byte[] buf = line.getBytes(StandardCharsets.UTF_8.name());
output.write(buf, 0, buf.length);
Is there any way to convert Java String to a byte[] (not the boxed Byte[])?
In trying this:
System.out.println(response.split("\r\n\r\n")[1]);
System.out.println("******");
System.out.println(response.split("\r\n\r\n")[1].getBytes().toString());
and I'm getting separate outputs. Unable to display 1st output as it is a gzip string.
<A Gzip String>
******
[B#38ee9f13
The second is an address. Is there anything I'm doing wrong? I need the result in a byte[] to feed it to gzip decompressor, which is as follows.
String decompressGZIP(byte[] gzip) throws IOException {
java.util.zip.Inflater inf = new java.util.zip.Inflater();
java.io.ByteArrayInputStream bytein = new java.io.ByteArrayInputStream(gzip);
java.util.zip.GZIPInputStream gzin = new java.util.zip.GZIPInputStream(bytein);
java.io.ByteArrayOutputStream byteout = new java.io.ByteArrayOutputStream();
int res = 0;
byte buf[] = new byte[1024];
while (res >= 0) {
res = gzin.read(buf, 0, buf.length);
if (res > 0) {
byteout.write(buf, 0, res);
}
}
byte uncompressed[] = byteout.toByteArray();
return (uncompressed.toString());
}
The object your method decompressGZIP() needs is a byte[].
So the basic, technical answer to the question you have asked is:
byte[] b = string.getBytes();
byte[] b = string.getBytes(Charset.forName("UTF-8"));
byte[] b = string.getBytes(StandardCharsets.UTF_8); // Java 7+ only
However the problem you appear to be wrestling with is that this doesn't display very well. Calling toString() will just give you the default Object.toString() which is the class name + memory address. In your result [B#38ee9f13, the [B means byte[] and 38ee9f13 is the memory address, separated by an #.
For display purposes you can use:
Arrays.toString(bytes);
But this will just display as a sequence of comma-separated integers, which may or may not be what you want.
To get a readable String back from a byte[], use:
String string = new String(byte[] bytes, Charset charset);
The reason the Charset version is favoured, is that all String objects in Java are stored internally as UTF-16. When converting to a byte[] you will get a different breakdown of bytes for the given glyphs of that String, depending upon the chosen charset.
String example = "Convert Java String";
byte[] bytes = example.getBytes();
Simply:
String abc="abcdefghight";
byte[] b = abc.getBytes();
Try using String.getBytes(). It returns a byte[] representing string data.
Example:
String data = "sample data";
byte[] byteData = data.getBytes();
You can use String.getBytes() which returns the byte[] array.
You might wanna try return new String(byteout.toByteArray(Charset.forName("UTF-8")))
I know I'm a little late tothe party but thisworks pretty neat (our professor gave it to us)
public static byte[] asBytes (String s) {
String tmp;
byte[] b = new byte[s.length() / 2];
int i;
for (i = 0; i < s.length() / 2; i++) {
tmp = s.substring(i * 2, i * 2 + 2);
b[i] = (byte)(Integer.parseInt(tmp, 16) & 0xff);
}
return b; //return bytes
}
i had to conwert a int to decimal 3 byte 129 to 1 2 9
Byte data
int i1 = 129
int i3 = (i1 / 100);
i1 = i1 - i3*100;
int i2 = (i1 / 10);
i1 = i1 - i2*10;
data [1]= (byte) i1
data [2]= (byte) i2
data [3]= (byte) i3
It is not necessary to change java as a String parameter. You have to change the c code to receive a String without a pointer and in its code:
Bool DmgrGetVersion (String szVersion);
Char NewszVersion [200];
Strcpy (NewszVersion, szVersion.t_str ());
.t_str () applies to builder c ++ 2010
I have a big String that was once converted to a ByteBuffer & then while reading later several times, only a portion of the String(overview of the text) needs to be presented, so I want to convert only a part of the ByteBuffer to String.
Is it possible to convert only a part of bytebuffer to string rather than [converting entire Bytebuffer to String & then using substring()]
try {
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(yourstr));
bbuf.position(0);
bbuf.limit(200);
CharBuffer cbuf = decoder.decode(bbuf);
String s = cbuf.toString();
System.out.println(s);
} catch (CharacterCodingException e) {
}
Which should return chars from the byte buffer starting at 0. byte and ending in 200.
Or rather:
ByteBuffer bbuf = ByteBuffer.wrap(yourstr.getBytes());
bbuf.position(0);
bbuf.limit(200);
byte[] bytearr = new byte[bbuf.remaining()];
bbuf.get(bytearr);
String s = new String(bytearr);
Which does the same but without explicit character decoding/encoding.
Decoding of course does happen in constructor of String s and it is platform dependent, so watch out.
// convert all byteBuffer to string
String fullByteBuffer = new String(byteBuffer.array());
// convert part of byteBuffer to string
byte[] partOfByteBuffer = new byte[PART_LENGTH];
System.arraycopy(fullByteBuffer.array(), 0, partOfByteBuffer, 0, partOfByteBuffer.length);
String partOfByteBufferString = new String(partOfByteBuffer.array());
The question is in comments in the code, I thought that'd be an easier way to ask...
Easy question, but I can't seem to find an answer. I want to convert a String to it's byte[] (easy, String.getBytes()). Then I want to convert a String of bytes (101011010101001 for example) to a byte[] and get the String value of that (that's easy too: new String(byte[]))
Here's what I've got so far:
Scanner scan = new Scanner(System.in);
String string = scan.nextLine();
String byteString = "";
for (byte b : string.getBytes()) {
byteString += b;
}
System.out.println(byteString);
//This isn't exactly how it works, these two parts in separate methods, but you get the idea...
String byteString = scan.nextLine();
byte[] bytes = byteString.literalToBytes() //<== or something like that...
//The line above is pretty much all I need...
String string = new String(bytes);
System.out.println(string);
This won't work. The problem is that when you convert your bytes to a string you are going to get a string like
2532611134
So analyzing this string, is the first byte 2, or 25, or 253?
The only way to make this work would be to use a DecimalFormat and make sure every byte is 3 characters long in your string
EDIT
Please see this answer for a solution.
With this you can:
String string = scan.nextLine();
String convertByte = convertByte(string.getBytes());
System.out.println(convertByte);
String byteString = scan.nextLine();
System.out.println(new String(convertStr(byteString)));
Alright, because the commenter who pointed me to this question (which lead me to this answer) isn't going to answer, I'll just post the solution here:
Scanner scan = new Scanner(System.in);
String pass = scan.nextLine();
StringBuilder byteString = new StringBuilder();
for (byte b : pass.getBytes()) {
b = (byte) (b);
byteString.append(b).append(","); //appending that comma is what does the trick.
}
System.out.println(byteString);
//
String[] split = byteString.toString().split(","); //splitting by that comma is what does the trick... too...
byte[] bytes = new byte[split.length];
for (int i = 0; i < split.length; i++) {
bytes[i] = (byte) (Byte.valueOf(split[i]).byteValue());
}
System.out.println(new String(bytes));
I guess what you want is this
// to get back the string from byte array
StringBuilder byteString = new StringBuilder();
for (byte b : string.getBytes()) {
byteString.append((char)b);
}
System.out.println(byteString.toString());
// to get the binary representation from string
StringBuilder byteString = new StringBuilder();
for (byte b : string.getBytes()) {
System.out.print(Integer.toBinaryString((int)b));
}
System.out.println(byteString.toString());