I need to save a binary stream, that I will later convert to text. Since binary streams don't exist in Java, I just saved my 'bits' in a stream of 'bytes' just to test my code. Now I have a stream of bytes where 1 bit is encoded on 1 byte.
byte [] stream = new byte [1500];
int str = 0;
byte [] data = new byte [1];
for (int i = 0; i<original.cols(); i++)
{
for (int j= 0; j<original.rows(); j++)
{
original.get(j,i, data);
if ((data[0]==0))
{
stream [str]=0;
str = str+1;
}
else
{
stream [str]=1;
str = str+1;
}
}
}
Can anyone help me to properly save my bits encoded in a stream of bytes, where 1 byte would represent 8 bits ?
A java.util.BitSet contains helper methods for dealing with raw bits, and conversions to and from byte arrays. In the following example, bytes will contain a single byte:
int numberOfBits = 8;
BitSet bitSet = new BitSet(numberOfBits);
bitSet.set(3, true);
bitSet.set(7, true);
byte[] bytes = bitSet.toByteArray();
Related
I have generated SipHash for 1 string and 2 long values (for many such combinations of string and long). I used -
Hasher hash = Hashing.sipHash24().newHasher().putUnencodedChars("abcd").putLong(123).putLong(123);
Now I converted this hash to string using -
String hashString = hash.hash().toString();
But, I wanted the bytes array of the string, Could there be any way, so that I am able to get the bytes array from this string same as to the one I would have got from byte[] hashBytes = hash.hash().asBytes(); I wanted to convert the string I had got from these hashes to bytes array.
Actually I realised that the bytes array was using only 8 bytes of space for the siphash, where as the length of string was 18 bytes. So , I guess storing the hash as bytes array would be more optimised.
BaseEncoding.base16().lowerCase().decode(string)
should convert HashCode.toString() back into the byte array you would've gotten from asBytes().
You can parse the string back into a HashCode instance with HashCode.fromString(string). Then you can call .asBytes() on the HashCode instance to get back a copy of the underlying byte[].
So basically you want:
byte[] bytes = HashCode.fromString(string).asBytes();
Here is the code to get bytes array from string -
public static byte[] getBytes(String hashString) {
final byte[] bytes = new byte[8];
HashMap<Character, String> bin = new HashMap<>();
bin.put('0', "0000");
bin.put('1', "0001");
bin.put('2', "0010");
bin.put('3', "0011");
bin.put('4', "0100");
bin.put('5', "0101");
bin.put('6', "0110");
bin.put('7', "0111");
bin.put('8', "1000");
bin.put('9', "1001");
bin.put('a', "1010");
bin.put('b', "1011");
bin.put('c', "1100");
bin.put('d', "1101");
bin.put('e', "1110");
bin.put('f', "1111");
for (int i = 0; i < 16 && i < hashString.length(); i += 2) {
final BitSet bitset = new BitSet(8);
String byteBinary = bin.get(hashString.charAt(i)) + bin.get(hashString.charAt(i + 1));
for (int j = 0; j<8; j++) {
if (byteBinary.charAt(j) == '1')
bitset.set(7-j, true);
else
bitset.set(7-j, false);
}
bytes[i/2] = bitset.toByteArray()[0];
//System.out.println(byteBinary);
}
return bytes;
}
How do we understand the defined length of the byte array?
For instance in this example we are defining here that the length of the byte array is 100.
What if the data that would have to be written to the byte array would be longer than 100 bytes?
The same for the result variable here. I don't understand how these lengths work and how to choose a proper length of a byte array for the needs if you don't know how big your data will be?
try {
// Encode a String into bytes
String inputString = "blahblahblah";
byte[] input = inputString.getBytes("UTF-8");
// Compress the bytes
**byte[] output = new byte[100];**
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.finish();
int compressedDataLength = compresser.deflate(output);
compresser.end();
// Decompress the bytes
Inflater decompresser = new Inflater();
decompresser.setInput(output, 0, compressedDataLength);
**byte[] result = new byte[100];**
int resultLength = decompresser.inflate(result);
decompresser.end();
// Decode the bytes into a String
String outputString = new String(result, 0, resultLength, "UTF-8");
} catch(java.io.UnsupportedEncodingException ex) {
// handle
} catch (java.util.zip.DataFormatException ex) {
// handle
}
And for this example, the byte array that is used here as input, is actually called a buffer, how do we understand it?
Here, when you call compresser.deflate(output) you cannot know the size needed for output unless you know how this method works. But this is not a problem since output is meant as a buffer.
So you should call deflate multiple times and insert output in another object like an OutputStream, like this:
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buffer);
outputStream.write(buffer, 0, count);
}
Same goes for inflating.
By allocating 100 bytes to the byte array, JVM guarantees that a buffer large enough to hold 100 JVM defined bytes (i.e. 8 bits) is available to the caller. Any attempt to access the array with more than 100 bytes would result in exception e.g. ArrayIndexOutOfBoundException in case you directly try to access the array by array[101].
In case the code is written as your demo, the caller assumes the data length never exceeds 100.
When writing to a binary file like this:
byte[] content = {1,2,3};
FileOutputStream output = new FileOutputStream("data.bin");
DataOutputStream fileName = new DataOutputStream(output);
fileName.writeInt(content.length);
for (int i = 0; i < content.length; i++)
{
fileName.writeInt(content[i]);
System.out.println(content[i]);
}
fileName.close();
When reading it back using FileInputStream/DataInputStream and .readInt() everything is ok.
(If i use .skip(4); because the first one seems to contain a value wich is the number of digits written)
However, if the byte[] content is replaced with input using scanner.
java.util.Scanner in = new java.util.Scanner(System.in);
String inputAsString = in.nextLine();
byte[] content = inputAsString.getBytes();
I noticed it is written to the binaryfile in decimal. 1 becomes 49, 2 is 50, 3 is 51 ...
My question is how can i read it back to 1, 2, 3 just like the first example with the hardcoded byte array.
When you read in data from input it's a string. So you're getting ascii/utf-x bytes. So the value you're writing is the byte. You want to turn the input you read into an int:
int toWrite = parseInt(inputAsString);
fileName.writeInt(toWrite);
Note that 51 is ascii value assigned to the character '3'
If you write it out as an int you should be able to read it in as such as well.
Use in.nextByte() in a loop to read the the entries as byte.
byte[] bytes = new byte[SIZE];
int indx = 0;
while(in.hasNextByte()){
bytes[indx++] = in.nextByte();
}
EDIT: If you don't know the size then:
List<Byte> byteList = new ArrayList<Byte>();
while(in.hasNextByte()){
byteList.add(in.nextByte());
}
Byte[] bytes = byteList.toArray(new Byte[]{});
I am currently working on a Project which is in Objective C.
I need to use Functions of Java class DataOutputStream like writeChars, writeLong, flush and some functions of ByteArrayOutputStream Class.
Specifically, what can I use in Objective C which has the same functionality as the DataOutputStream and ByteArrayOutputStream class?
This is the code i need to convert into Objective C.
public static byte[] getByteArray(String key, long counter) throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
if (key != null)
{
dos.writeChars(key);
}
dos.writeLong(counter);
dos.flush();
byte[] data = bos.toByteArray();
return data;
}
NSLog();
the above method takes string and objects as arguments.
As,
NSLog(#"Hi this is demo of string printing.");
NSLog(#"Hi this is integer %d",intValue);//this is like printf isnt it?
EDIT:
Either %b, or convert it into NSData object and then print using %#. Obj-c uses %# for all kind of object.
unsigned int a = 0x000000FF;
NSLog(#"%x", a);//prints the most significant digits first
What you want is convert primitive data types into raw bytes.
NSMutableData* dataBuffer = [NSMutableData data]; //obj-c byte array
long long number = 123456LL; //note that long long is needed in obj-c to represent 64bit numbers
NSData* numberData = [NSData dataWithBytes:&number length:sizeof(number)];
[dataBuffer appendData:numberData];
NSString* text = #"abcdefg";
const char* rawText = [text cStringUsingEncoding:NSUTF8StringEncoding]; //java uses utf8 encoding
NSData* textData = [NSData dataWithBytes:rawText length:strlen(rawText)];
[dataBuffer appendData:textData];
return dataBuffer;
No flush() is necessary (I believe in Java is not neccessary with ByteArrayOutputStream either)
This is a bit simplified, note that when Java writes a string, the first two bytes are always the string length. Java also writes numbers in Big Endian. We are writing them in system byte-order. That shouldn't be a problem if you don't want to send the binary data to other devices.
You can switch byte order using utilities in CFByteOrderUtils.h or you can get the number in Big Endian directly by the following:
- (NSData*)bytesFromLongLong:(long long)number {
char buffer[8];
for (int i = sizeof(buffer) - 1; i >= 0; i--) {
buffer[i] = (number & 0xFF);
number >> 8;
}
return [NSData dataWithBytes:buffer length:sizeof(buffer)]
}
Hi I am trying to implement the interface SourceStream in my application and overrides the method read(byte[],off,len) and I read the bytes from a server.But I want to convert those byte stream into String for that I used a string object by new String(byte[]) but it asks the initial byte in off and length of the bytes ie len as parameters..Why it is asking like that, as we contain only Strring(bye[])only. can any one help me...Thanks
If you just have a byte[] then you can create a new String via the String(byte[],int,int) constructor provided by the API.
In your case you would do
byte[] myBytes = ("Hello, World!").getBytes();
String myString = new String(myBytes, 0, myBytes.length);
System.out.println(myString);
EDIT:
Try something like this:
int readLength = (len > bufSize ? bufSize : len);
for (int i = 0; i < readLength; i++) {
b[off + i] = buffers[PBuf][PByte];
}
String metaSt = new String(b, 0, readLength);
Just provide 0 as the initial offset and yourArray.Length as the length and you're done. Quite why a method that takes just a byte array isn't provided is anyones guess - probably just to avoid 101 variations of the method.