How to convert a String array to a Byte array? (java) - java

I have a one dimensional String array that I want to convert into a one dimensional byte array. How do I do this? Does this require ByteBuffer? How can I do this? (The strings can be any length, just want to know how to go about doing such an act. And after you convert it into a byte array how could I convert it back into a String array?
-Dan

Array to Array you should convert manually with parsing into both sides, but if you have just a String you can String.getBytes() and new String(byte[] data);
like this
public static void main(String[] args) {
String[] strings = new String[]{"first", "second"};
System.out.println(Arrays.toString(strings));
byte[][] byteStrings = convertToBytes(strings);
strings = convertToStrings(byteStrings);
System.out.println(Arrays.toString(strings));
}
private static String[] convertToStrings(byte[][] byteStrings) {
String[] data = new String[byteStrings.length];
for (int i = 0; i < byteStrings.length; i++) {
data[i] = new String(byteStrings[i], Charset.defaultCharset());
}
return data;
}
private static byte[][] convertToBytes(String[] strings) {
byte[][] data = new byte[strings.length][];
for (int i = 0; i < strings.length; i++) {
String string = strings[i];
data[i] = string.getBytes(Charset.defaultCharset()); // you can chose charset
}
return data;
}
for one byte[] from string[] you have to:
to byteArray concat byte arrays from each string using some delimeter
from bytearray split by te same delimiter and create String as I
described above.

You don't say what you want to do with the bytes (aside from convert them back to a String[] afterward), but assuming you can just treat them as an opaque bag of data (so you can save them to a file or send them over the network or whatnot, but you don't need to examine or modify them in any way), I think your best bet is to use serialization. To serialize your string-array, you would write something like:
final String[] stringArray = { "foo", "bar", "baz" };
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final ObjectOutputStream objectOutputStream =
new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(stringArray);
objectOutputStream.flush();
objectOutputStream.close();
final byte[] byteArray = byteArrayOutputStream.toByteArray();
and to recover it afterward, you'd write the reverse:
final ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(byteArray);
final ObjectInputStream objectInputStream =
new ObjectInputStream(byteArrayInputStream);
final String[] stringArray2 = (String[]) objectInputStream.readObject();
objectInputStream.close();

You can check this
package javaapplication2;
import java.util.Arrays;
/**
*
* #author Ali
*/
public class JavaApplication2 {
public static byte[] to_byte(String[] strs) {
byte[] bytes=new byte[strs.length];
for (int i=0; i<strs.length; i++) {
bytes[i]=Byte.parseByte(strs[i]);
}
return bytes;
}
public static void main(String[] args) {
String[] input = {"1","2","3"}; //original data
byte[] byteArray = to_byte(input);//data to byte array
String[] recovered=Arrays.toString( byteArray).split(",");// recovered data
}
}

First declare the string like I declared here str="Suresh"
Second use getBytes() to convert it in bytes
getBytes returns the array of byte.
String str="Suresh";
byte[] s=str.getBytes();

String.getBytes()? is what you're looking for.

I would treat this as a serialization problem and just implemented it as follows(complete and working Java code):
import java.nio.ByteBuffer;
import java.util.ArrayList;
public class Serialization {
public static byte[] serialize(String[] strs) {
ArrayList<Byte> byteList = new ArrayList<Byte>();
for (String str: strs) {
int len = str.getBytes().length;
ByteBuffer bb = ByteBuffer.allocate(4);
bb.putInt(len);
byte[] lenArray = bb.array();
for (byte b: lenArray) {
byteList.add(b);
}
byte[] strArray = str.getBytes();
for (byte b: strArray) {
byteList.add(b);
}
}
byte[] result = new byte[byteList.size()];
for (int i=0; i<byteList.size(); i++) {
result[i] = byteList.get(i);
}
return result;
}
public static String[] unserialize(byte[] bytes) {
ArrayList<String> strList = new ArrayList<String>();
for (int i=0; i< bytes.length;) {
byte[] lenArray = new byte[4];
for (int j=i; j<i+4; j++) {
lenArray[j-i] = bytes[j];
}
ByteBuffer wrapped = ByteBuffer.wrap(lenArray);
int len = wrapped.getInt();
byte[] strArray = new byte[len];
for (int k=i+4; k<i+4+len; k++) {
strArray[k-i-4] = bytes[k];
}
strList.add(new String(strArray));
i += 4+len;
}
return strList.toArray(new String[strList.size()]);
}
public static void main(String[] args) {
String[] input = {"This is","a serialization problem;","string concatenation will do as well","in some cases."};
byte[] byteArray = serialize(input);
String[] output = unserialize(byteArray);
for (String str: output) {
System.out.println(str);
}
}
}
The idea is that in the resulting byte array we store the length of the first string(which is always 4 bytes if we use the type int), followed by the bytes of the first string(whose length can be read later from the preceding 4 bytes), then followed by the length of the second string and the bytes of the second string, and so on. This way, the string array can be recovered easily from the resulting byte array, as demonstrated by the code above. And this serialization approach can handle any situation.
And the code can be much simpler if we make an assumption to the input string array:
public class Concatenation {
public static byte[] concatenate(String[] strs) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<strs.length; i++) {
sb.append(strs[i]);
if (i != strs.length-1) {
sb.append("*.*"); //concatenate by this splitter
}
}
return sb.toString().getBytes();
}
public static String[] split(byte[] bytes) {
String entire = new String(bytes);
return entire.split("\\*\\.\\*");
}
public static void main(String[] args) {
String[] input = {"This is","a serialization problem;","string concatenation will do as well","in some cases."};
byte[] byteArray = concatenate(input);
String[] output = split(byteArray);
for (String str: output) {
System.out.println(str);
}
}
}
The assumption is that *.* does not exist in any string from the input array. In other words, if you know in advance some special sequence of symbols won't appear in any string of the input array, you may use that sequence as the splitter.

You can iterate for each string and keep appending to the final byte array.
String example = "This is an example";
//Convert String to byte[] using .getBytes() function
byte[] bytes = example.getBytes();
//Convert byte[] to String using new String(byte[])
String s = new String(bytes);

Related

How to put a large text file in to Array?

I have a large text file. I want to put every character in the text file, in to Character array. I use this code to put it.
List<String> set = new ArrayList<String>();
BufferedReader bf = new BufferedReader(new FileReader(file_path));
String check_line=bf.readLine();
while(check_line!=null){
set.add(check_line);
check_line=bf.readLine();
}
ArrayList<Character> charr = new ArrayList<Character>();
for(int j=0;j<set.size();++j){
String str=set.get(j);
for (int x = 0; x < str.length(); x ++){
charr.add(str.charAt(x));
}}
return charr;
But it takes long time.Is there any efficient way to do this?
You can use for each line
char[] x = str.toCharArray();
With Java 8:
public static void main(final String[] args) throws IOException {
final Path file = Paths.get("path", "to", "file");
final Character[] characters = toCharacters(file);
}
public static Character[] toCharacters(final Path file) throws IOException {
try (final Stream<String> lines = Files.lines(file)) {
return lines.flatMapToInt(String::chars).
mapToObj(x -> (char) x).
toArray(Character[]::new);
}
}
More efficient coding wise, and fewer intermediate collections created. Not sure it will be much faster however as this involves file IO which is very slow.
Why do you use a list of Strings as a temp variable and don't directly store to your Character List?
ArrayList<Character> charr = new ArrayList<Character>();
String check_line=bf.readLine();
while(check_line!=null){
for(char c : check_line.toCharArray())
charr.add(c);
check_line=bf.readLine();
}
return charr;
Just concatenate the line into one string and then convert them to an char array.
public char[] extractCharArray(String fileName) {
char[] charArray = null;
try(BufferedReader bf = new BufferedReader(new FileReader(fileName))) {
StringBuilder completeFileString = new StringBuilder();
String check_line=bf.readLine();
while(check_line!=null){
completeFileString = completeFileString.append(check_line);
check_line=bf.readLine();
}
charArray = completeFileString.toString().toCharArray();
} catch(IOException ex) {
//Handle the exception
}
return charArray;
}

Parse byte[] from String initializer "new byte[]{1,2,3}"

Hi Team,Firstly I don't want a byte[] array made from the actual String/char[]
//NO!
String s = "abc";
byte[] bytes = s.getBytes();
I want a byte[] array constructed by the contents and representation of the String, like so.
byte[] b = "new byte[]{1,2,3}"
//Again I don't want >> byte[] b = new String("new byte[]{1,2,3}").getBytes();
thanks Team.
This worked for me -
/**
* Parse a properly formatted String into a byte array.
*
* #param in
* The string to parse - must be formatted
* "new byte[]{1,2,n}"
* #return The byte array parsed from the input string.
*/
public static byte[] parseByteArrayFromString(
String in) {
in = (in != null) ? in.trim() : "";
// Opening stanza.
if (in.startsWith("new byte[]{")) {
// Correct closing brace?
if (in.endsWith("}")) {
// substring the input.
in = in.substring(11, in.length() - 1);
// Create a list of Byte(s).
List<Byte> al = new ArrayList<Byte>();
// Tokenize the input.
StringTokenizer st = new StringTokenizer(in,
",");
while (st.hasMoreTokens()) {
String token = st.nextToken();
// Add a Byte.
al.add(Byte.valueOf(token.trim()));
}
// Convert from the List to an Array.
byte[] ret = new byte[al.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = al.get(i);
}
return ret;
}
}
return new byte[] {};
}
public static void main(String[] args) {
byte[] vals = parseByteArrayFromString("new byte[]{1,2,3}");
System.out.println(Arrays.toString(vals));
}
Well, you could always just traverse through the array and put those values in a string, then put those in a byte array.
String d = "new byte[]{";
for(int i = 0; i < s.length() - 1; i++)
d += s.charAt(i) +",";
d += s.charAt(s.length() - 1) + "}";
byte[] b = d.getBytes();
You can extract bytes by using regular expression, such as:
Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
Byte.parseByte(matcher.group(0)).byteValue(); // Use this
}
In the while loop, use can add them to an array to use it later or print it to console, or any else. It's up to you.
For sure that input string is correct, add another pattern to check that string if necessary. For example:
Pattern.compile("new byte\\[\\] ?\\{((\\d+),? *)+\\}");

Converting array string to string and back in Java

I have an array String[] in Java, and must first encode/convert it into a String and then further in the code covert it back to the String[] array. The thing is that I can have any character in a string in String[] array so I must be very careful when encoding. And all the information necessary to decode it must be in the final string. I can not return a string and some other information in an extra variable.
My algorithm I have devised so far is to:
Append all the strings next to each other, for example like this:
String[] a = {"lala", "exe", "a"}
into
String b = "lalaexea"
Append at the end of the string the lengths of all the strings from String[], separated from the main text by $ sign and then each length separated by a comma, so:
b = "lalaexea$4,3,1"
Then when converting it back, I would first read the lengths from behind and then based on them, the real strings.
But maybe there is an easier way?
Cheers!
If you don't wanna spend so much time with string operations you could use java serialization + commons codecs like this:
public void stringArrayTest() throws IOException, ClassNotFoundException, DecoderException {
String[] strs = new String[] {"test 1", "test 2", "test 3"};
System.out.println(Arrays.toString(strs));
// serialize
ByteArrayOutputStream out = new ByteArrayOutputStream();
new ObjectOutputStream(out).writeObject(strs);
// your string
String yourString = new String(Hex.encodeHex(out.toByteArray()));
System.out.println(yourString);
// deserialize
ByteArrayInputStream in = new ByteArrayInputStream(Hex.decodeHex(yourString.toCharArray()));
System.out.println(Arrays.toString((String[]) new ObjectInputStream(in).readObject()));
}
This will return the following output:
[test 1, test 2, test 3]
aced0005757200135b4c6a6176612e6c616e672e537472696e673badd256e7e91d7b47020000787000000003740006746573742031740006746573742032740006746573742033
[test 1, test 2, test 3]
If you are using maven, you can use the following dependency for commons codec:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.2</version>
</dependency>
As suggested with base64 (two lines change):
String yourString = new String(Base64.encodeBase64(out.toByteArray()));
ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(yourString.getBytes()));
In case of Base64 the result string is shorter, for the code exposed below:
[test 1, test 2, test 3]
rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AAZ0ZXN0IDF0AAZ0ZXN0IDJ0AAZ0ZXN0IDM=
[test 1, test 2, test 3]
Regarding the times for each approach, I perform 10^5 executions of each method and the result was as follows:
String manipulation: 156 ms
Hex: 376 ms
Base64: 379 ms
Code used for test:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.StringTokenizer;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
public class StringArrayRepresentationTest {
public static void main(String[] args) throws IOException, ClassNotFoundException, DecoderException {
String[] strs = new String[] {"test 1", "test 2", "test 3"};
long t = System.currentTimeMillis();
for (int i =0; i < 100000;i++) {
stringManipulation(strs);
}
System.out.println("String manipulation: " + (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
for (int i =0; i < 100000;i++) {
testHex(strs);
}
System.out.println("Hex: " + (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
for (int i =0; i < 100000;i++) {
testBase64(strs);
}
System.out.println("Base64: " + (System.currentTimeMillis() - t));
}
public static void stringManipulation(String[] strs) {
String result = serialize(strs);
unserialize(result);
}
private static String[] unserialize(String result) {
int sizesSplitPoint = result.toString().lastIndexOf('$');
String sizes = result.substring(sizesSplitPoint+1);
StringTokenizer st = new StringTokenizer(sizes, ";");
String[] resultArray = new String[st.countTokens()];
int i = 0;
int lastPosition = 0;
while (st.hasMoreTokens()) {
String stringLengthStr = st.nextToken();
int stringLength = Integer.parseInt(stringLengthStr);
resultArray[i++] = result.substring(lastPosition, lastPosition + stringLength);
lastPosition += stringLength;
}
return resultArray;
}
private static String serialize(String[] strs) {
StringBuilder sizes = new StringBuilder("$");
StringBuilder result = new StringBuilder();
for (String str : strs) {
if (sizes.length() != 1) {
sizes.append(';');
}
sizes.append(str.length());
result.append(str);
}
result.append(sizes.toString());
return result.toString();
}
public static void testBase64(String[] strs) throws IOException, ClassNotFoundException, DecoderException {
// serialize
ByteArrayOutputStream out = new ByteArrayOutputStream();
new ObjectOutputStream(out).writeObject(strs);
// your string
String yourString = new String(Base64.encodeBase64(out.toByteArray()));
// deserialize
ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(yourString.getBytes()));
}
public static void testHex(String[] strs) throws IOException, ClassNotFoundException, DecoderException {
// serialize
ByteArrayOutputStream out = new ByteArrayOutputStream();
new ObjectOutputStream(out).writeObject(strs);
// your string
String yourString = new String(Hex.encodeHex(out.toByteArray()));
// deserialize
ByteArrayInputStream in = new ByteArrayInputStream(Hex.decodeHex(yourString.toCharArray()));
}
}
Use a Json parser like Jackson to serialize/deserialize other type of objects as well like integer/floats ext to strings and back.
Just use a known separator (such as # or # to append your strings), then use yourString.split(yourSeparator) to get an array from it.
I would use the symbol between the words to later use the String#split method to get the String back. Based in your $ symbol example, it would be
public String mergeStrings(String[] ss) {
StringBuilder sb = new StringBuilder();
for(String s : ss) {
sb.append(s);
sb.append('$');
}
return sb.toString();
}
public String[] unmergeStrings(String s) {
return s.split("\\$");
}
Note that in this example, I add a double \ before the $ symbol because the String#split method receives a regular expression as parameter, and the $ symbol is a special character in regex.
public String processData(String[] ss) {
String mergedString = mergeStrings(ss);
//process data...
//a little example...
for(int i = 0; i < mergedString.length(); i++) {
if (mergedString.charAt(i) == '$') {
System.out.println();
} else {
System.out.print(mergedString.charAt(i));
}
}
System.out.println();
//unmerging the data again
String[] oldData = unmergeStrings(mergedString);
}
In order to support any character in your String[], it would be better to set not a single character as separator but instead another String. The methods would turn into this:
public static final String STRING_SEPARATOR = "#|$|#";
public static final String STRING_SEPARATOR_REGEX = "#\\|\\$\\|#";
public String mergeStrings(String[] ss) {
StringBuilder sb = new StringBuilder();
for(String s : ss) {
sb.append(s);
sb.append(STRING_SEPARATOR);
}
return sb.toString();
}
public String[] unmergeStrings(String s) {
return s.split(STRING_SEPARATOR_REGEX);
}

String(byte array) to byte array

i need to convert from string to same byte array:
String data = request.getParameter("data");
byte[] dataByte = new byte[]{};
data = -60,-33,-10,-119,126,114,-61,-31,55,-102,-35,-72,114,77,115,72,79,-117,102,64,98,-20,-75,27,58,-59,86,-97,106,19,-112,-79,100,105,115,107,100,105,114,101,99,116,111,114,95,115,97,102,101,46,99,111,110,102,105,103,49,52,53,53,83,112,97,99,101,115,83,116,111,114,101,114,117,99,111,110,116,101,110,116,85,114,108,61,115,116,111,114,101,58,47,47,50,48,49,50,47,49,48,47,49,47,57,47,53,50,47,57,100,48,48,48,48,55,97,45,54,50,48,48,45,52,54,52,102,45,97,48,48,97,45,50,52,97,100,52,98,100,55,50,53,53,48,46,98,105,110,124,109,105,109,101,116,121,112,101,61,97,112,112,108,105,99,97,116,105,111,110,47,111,99,116,101,116,45,115,116,114,101,97,109,124,115,105,122,101,61,52,53,57,53,49,124,101,110,99,111,100,105,110,103,61,85,84,70,45,56,124,108,111,99,97,108,101,61,114,117,95,124,105,100,61,52,49,48,56,101,57,100,100,50,100,56,45,56,102,54,97,45,52,54,55,54,45,56,53,99,57,45,50,52,54,102,55,57,57,55,101,102,48,99,77,111,110,32,79,99,116,32,48,49,32,48,57,58,53,50,58,49,53,32,78,79,86,83,84,32,50,48,49,50,119,111,114,107,115,112,97,99,101,97,100,109,105,110,97,100,109,105,110
String[] dataArray = data.split(",")
You can then iterate over that dataArray and then create byte[] out of it.
String dataArray[] = data.split(",");
byte[] bytes = new byte[dataArray.length];
int count = 0;
for(String str : dataArray)
{
bytes[count++] = Byte.parseByte(str);
}
If you know character encoding then you can use #String.getBytes
String.getBytes(String charsetName) will give you a byte-array. You will have to be careful re. specifying your character encoding.
Use StringTokenizer or String.split() method and parse each substring to byte. Take care with encoding.
Use String.split() and iterate over the resulting array:
String[] array = data.split(",");
byte[] dataByte = new byte[ array.length ];
for ( int i=0 ; i<array.length ; i++ ) { dataByte[ i ] = Byte.parseByte( array[ i ] ); }
Cheers,
You can use String#getBytes() method for this purpose: -
String data = request.getParameter("data");
byte[] dataByte = data.getBytes()
It uses the default character encoding.. You can specify your own..
See String#getBytes(Charset)
Or you can use Byte#parseByte(String) method in each value of the string array after splitting it: -
String data = request.getParameter("data");
String arr[] = data.split(",");
byte[] newarr = new byte[arr.length];
int count = 0;
for (String val: arr) {
newarr[count++] = Byte.parseByte(val);
System.out.println(Byte.parseByte(val) + ", ");
}

Hex-encoded String to Byte Array

String str = "9B7D2C34A366BF890C730641E6CECF6F";
I want to convert str into byte array, but str.getBytes() returns 32 bytes instead of 16.
I think what the questioner is after is converting the string representation of a hexadecimal value to a byte array representing that hexadecimal value.
The apache commons-codec has a class for that, Hex.
String s = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = Hex.decodeHex(s.toCharArray());
Java SE 6 or Java EE 5 provides a method to do this now so there is no need for extra libraries.
The method is DatatypeConverter.parseHexBinary
In this case it can be used as follows:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = DatatypeConverter.parseHexBinary(str);
The class also provides type conversions for many other formats that are generally used in XML.
Use:
str.getBytes("UTF-16LE");
I know it's late but hope it will help someone else...
This is my code: It takes two by two hex representations contained in String and add those into byte array.
It works perfectly for me.
public byte[] stringToByteArray (String s) {
byte[] byteArray = new byte[s.length()/2];
String[] strBytes = new String[s.length()/2];
int k = 0;
for (int i = 0; i < s.length(); i=i+2) {
int j = i+2;
strBytes[k] = s.substring(i,j);
byteArray[k] = (byte)Integer.parseInt(strBytes[k], 16);
k++;
}
return byteArray;
}
That should do the trick :
byte[] bytes = toByteArray(Str.toCharArray());
public static byte[] toByteArray(char[] array) {
return toByteArray(array, Charset.defaultCharset());
}
public static byte[] toByteArray(char[] array, Charset charset) {
CharBuffer cbuf = CharBuffer.wrap(array);
ByteBuffer bbuf = charset.encode(cbuf);
return bbuf.array();
}
try this:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
String[] temp = str.split(",");
bytesArray = new byte[temp.length];
int index = 0;
for (String item: temp) {
bytesArray[index] = Byte.parseByte(item);
index++;
}
I assume what you need is to convert a hex string into a byte array that equals that means the same thing as that hex string?
Adding this method should do it for you, without any extra library importing:
public static byte[] hexToByteArray(String s) {
String[] strBytes = s.split("(?<=\\G.{2})");
byte[] bytes = new byte[strBytes.length];
for(int i = 0; i < strBytes.length; i++)
bytes[i] = (byte)Integer.parseInt(strBytes[i], 16);
return bytes;
}

Categories

Resources