I need to save in the first byte position of the number of characters that has a string. Then store the value of each of the characters in the following positions.
String cadena = new String ("Desarrollo");
byte valores[] = new byte [cadena.length()];
valores = cadena.getBytes();
Use a java.nio.ByteBuffer. Get the String representation as a byte[] based on some given character set. Write the size of the String first as an int, then write the byte[].
String cadena = new String("Desarollo");
byte[] bytes = cadena.getBytes("UTF-8");
ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length); // 4 being the size of an int in bytes
buffer.putInt(cadena.length());
buffer.put(bytes);
You can then get the underlying byte[] with
buffer.array();
You should write the String length as an int because byte has a maximum value of 127, which you will probably surpass very fast.
Related
I'm trying to implement a database in java using slotted pages , so basically what I want to do is to store my data in a specific number of bytes .
so this is the page where I have to store it .
protected byte[] myData = new byte[PAGE_SIZE*1024]; //array for storing my data
now I want to store an Integer in the first 4 bytes of myData , when I do that automatically is stored in just one byte if the Integer doesn't exceed 255 , but what I want to do is use 4 bytes for my Integer it doesn't matter if it's 1 or one billion .
my question is , is it possible to do that in java ? to control how many bytes my data must allocate , like I assign 3 to the first 4 bytes of my byte array ?.
if (recordFitsIntoPage(record)) {
byte [] fix_rec = new byte [record.getFixedLength()];
byte [] var_rec= new byte [record.getVariableLength()];
var_rec = var_rec(record);
fix_rec = fix_rec(record);
byte [] box = { (byte) record.getVariableLength() ,(byte) offsetEnd };
System.arraycopy(fix_rec, 0,data,offset,record.getFixedLength());
System.arraycopy(var_rec, 0,data,offsetEnd,record.getVariableLength());
read_bytes(data);
this.numRecords++;
}else {
throw new Exception("no more space left");
}
I have a fixed-sized variables that I need to store them in my case for example in 12 bytes , I have been using System.arraycopy() but it's not relevant in my case , after I execute the code I get out of bound exception "last source index 12 out of bounds for byte[9]"
because it uses just 9 bytes to store my Data not 12 .
This method creates an array of 32 bytes of any integer given - be it 1 or one billion:
private static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
byte[] src = b.toByteArray();
byte[] dest = new byte[numBytes];
boolean isFirstByteOnlyForSign = src[0] == 0;
int length = isFirstByteOnlyForSign ? src.length - 1 : src.length;
int srcPos = isFirstByteOnlyForSign ? 1 : 0;
int destPos = numBytes - length;
System.arraycopy(src, srcPos, dest, destPos, length);
return dest;
}
You have an array of byte ready to store:
byte[] myData = new byte[PAGE_SIZE*1024];
You have a hand-picked integer as well:
BigInteger myInteger = new BigInteger("50000000000");
Then we change our integer to 32-length byte[]
byte[] bytesOfInteger = bigIntegerToBytes(myInteger,32);
Finally, you copy first 4 bytes of integer to your byte[] myData
System.arraycopy(bytesOfInteger, 0, myData, 0, 3);
So this shows that you can allocate any decent big integer into a fixed 32 byte[].
i have following problem:
i have array of 2 int - its char ř how can i convert this array to string or char?
real values in array are: [-59, -103]
ř->[-59, -103]->ř
Thank you.
EDIT:
String specialChar = "ř";
System.out.println(specialChar);
byte[] tmp = specialChar.getBytes();
System.out.println(Arrays.toString(tmp)); //[-59, -103]
int[] byteIntArray = new int[2];
byteIntArray[0] = (int) tmp[0];
byteIntArray[1] = (int) tmp[1];
System.out.println(Arrays.toString(byteIntArray)); //[-59, -103]
//now i want convert byteIntArray to string
What about that?
byte[] byteArray = new byte[2];
byteArray[0] = (byte)byteIntArray[0];
byteArray[1] = (byte)byteIntArray[1];
String specialChar = new String(byteArray);
Note that String.getBytes() uses your local platform encoding to convert the string into a byte array. So the resulting byte array depends on your individual system settings.
If you want your byte array to be compatible to other systems, use a standard encoding like "UTF-8" instead:
byte[] tmp = specialChar.getBytes("UTF-8"); // String -> bytes
String s = new String(tmp, "UTF-8"); // bytes -> String
I have my below layout in which I need to represent my data and then finally I need to make one byte array out of that.
// below is my data layout -
// data key type which is 1 byte
// data key len which is 1 byte
// data key (variable size which is a key_len)
// timestamp (sizeof uint64_t)
// data size (sizeof uint16_t)
// data (variable size = data size)
So I started like this but I am having some confusion so got stuck -
// data layout
byte dataKeyType = 101;
byte dataKeyLength = 3;
// not sure how to represent key here
long timestamp = System.currentTimeMillis(); // which is 64 bit
short dataSize = 320; // what does this mean? it means size of data is 320 bytes?
// and now confuse as well how to represent data here, we can have any string data which can be converted to bytes
// and then make final byte array out of that
How do I represent this in one byte array using Byte Buffer? Any simple example will help me to understand better.
byte keyType = 101;
byte keyLength = 3;
byte[] key = {27, // or whatever your key is
55,
111};
long timestamp = System.currentTimeMillis();
// If your data is just a string, then you could do the following.
// However, you will likely want to provide the getBytes() method
// with an argument that specifies which text encoding you are using.
// The default is just the current platform's default charset.
byte[] data = "your string data".getBytes();
short dataSize = (short) data.length;
int totalSize = (1 + 1 + keyLength + 8 + 2 + dataSize);
ByteBuffer bytes = ByteBuffer.allocate(totalSize);
bytes.put(keyType);
bytes.put(keyLength);
bytes.put(key);
bytes.putLong(timestamp);
bytes.putShort(dataSize);
bytes.put(data);
// If you want everthing as a single byte array:
byte[] byteArray = bytes.array();
You can use Java's DataOutputStream class to dynamically generate the byte array. For example:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeByte(keyType);
dos.writeByte(keyLength);
dos.write(new byte[] { 1, 2, 3, ..., key_len-1 }, 0, key_len);
dos.writeLong(System.currentTimeMillis());
dos.writeShort(320);
dos.write(new byte[] { 1, 2, 3, ..., 319 }, 0, 320);
You should replace the two new byte[] {} parts by the array that contains the key bytes and the array that contains the data, respectively.
I am trying to use ByteBuffer properly with BigEndian byte order format..
I have couple of fields which I am trying to put together into a single ByteBuffer before storing it in Cassandra database.
That Byte Array which I will be writing into Cassandra is made up of three Byte Arrays as described below-
short employeeId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] attributeValue = os.toByteArray();
Now, I will write employeeId , lastModifiedDate and attributeValue together into a single Byte Array and that resulting Byte Array I will write into Cassandra and then I will be having my C++ program which will retrieve that Byte Array data from Cassandra and then deserialize it to extract employeeId , lastModifiedDate and attributeValue from it.
So to do this, I am using ByteBuffer with BigEndian byte order format.
I have put up this code together -
public static void main(String[] args) throws Exception {
String text = "Byte Buffer Test";
byte[] attributeValue = text.getBytes();
long lastModifiedDate = 1289811105109L;
short employeeId = 32767;
int size = 2 + 8 + 4 + attributeValue.length; // short is 2 bytes, long 8 and int 4
ByteBuffer bbuf = ByteBuffer.allocate(size);
bbuf.order(ByteOrder.BIG_ENDIAN);
bbuf.putShort(employeeId);
bbuf.putLong(lastModifiedDate);
bbuf.putInt(attributeValue.length);
bbuf.put(attributeValue);
bbuf.rewind();
// best approach is copy the internal buffer
byte[] bytesToStore = new byte[size];
bbuf.get(bytesToStore);
// write bytesToStore in Cassandra...
// Now retrieve the Byte Array data from Cassandra and deserialize it...
byte[] allWrittenBytesTest = bytesToStore;//magicFunctionToRetrieveDataFromCassandra();
ByteBuffer bb = ByteBuffer.wrap(allWrittenBytesTest);
bb.order(ByteOrder.BIG_ENDIAN);
bb.rewind();
short extractEmployeeId = bb.getShort();
long extractLastModifiedDate = bb.getLong();
int extractAttributeValueLength = bb.getInt();
byte[] extractAttributeValue = new byte[extractAttributeValueLength];
bb.get(extractAttributeValue); // read attributeValue from the remaining buffer
System.out.println(extractEmployeeId);
System.out.println(extractLastModifiedDate);
System.out.println(new String(extractAttributeValue));
}
Is there any better way of doing this, the way I am doing it currently? Or some minor improvements that we can do it here??
This is the first time I am using ByteBuffer so having little bit problem...
Can anyone take a look and let me know whether this is the right way to use ByteBuffer?
The default order is always BIG_ENDIAN, so you don't meed to set it. Also when you wrap() is is already rewind()ed.
Instead of copying the underlying array, I would use the underlying array.
Replace
bbuf.rewind();
// best approach is copy the internal buffer
byte[] bytesToStore = new byte[size];
bbuf.get(bytesToStore);
with
byte[] bytesToStore = bbuf.array();
I have a byte array of size 200 that has data received with socket.receive(). Let's say the packet data is "hello".
int size = 200;
DatagramPacket packet = new DatagramPacket(new byte[size], size);
socket.receive(packet);
byte[] byte1 = packet.getData();
I tried to convert the byte array into string, and the string length is 200 even though it prints out only 'hello' string.
String result = new String(byte1); // .toString();
System.out.println(result.length()); --> 200
System.out.println(result); ---> hello
How can I truncate the String to contain only "hello" when converting it from byte[]?
ADDED
Based on malchow's answer, this solved my issue:
int packetLength = packet.getLength();
byte[] byte1 = packet.getData();
String result = new String(byte1);
return result.substring(0, packetLength);
maybe you should try to check the length of the data received AFTER receiving it:
http://docs.oracle.com/javase/1.5.0/docs/api/java/net/DatagramPacket.html#getLength%28%29
this should be 4 (after the call to socket.receive())
If the extra bites are all empty/whitespace, trim() should do it.