This is the first time I stored binaries in rethinkdb and it went quiet well for storing them. The approach was quite simple (as documented in the command reference of ReQl. Also retrieving the binary from the Database again is fairly easy, yet I am struggling to convert it into a byte[]. The documentation says that r.binary() should return byte[] but in my case it returns a MapObject with a key called data. When retrieving that, data is an object but cannot be casted to byte[].
My code
MapObject mo = (MapObject)r.binary(continents.get("visibleMapImageBinary")).build();
//^^ is the MapObject that I can retrieve
String b = (String)tempor.get("data");
However I do not know how to get this back into a byte[]. Also tried to convert the String into a byte array, which also failed.
Thanks for any advice :)
After some trying out (and googling for what [B is, which I just thought stood for nothing but actually is the primtive of byte[]). This is my solution, no need to build() or even cast to the MapObject.
byte[] temp = (byte[])continents.get("visibleMapImageBinary");
I actually thought I tried this before, but it seems like I didn't ... well :)
Related
Edit: Figured it out, check my posted answer if you're having similar issues.
I know there are several questions about this issue, but none of their solutions are working for me.
In my model class I have made sure to use List instead of Arraylist to avoid Firebase issues, but am still getting this error. It's a lot of code but most questions ask for all the code so I'll post it all.
TemplateModelClass.java
//
I've used this basic model successfully many times. For the
HashMaps<String, List<String>>,
the String is an incremented Integer converted to String. The List's are just Strings in a List. Here's some sample JSON from Firebase:
//
Formatted that as best as I could. If you need a picture of it let me know and I'll get a screenshot
And am getting this error, as stated in the title:
com.google.firebase.database.DatabaseException: Expected a Map while deserializing, but got a class java.util.ArrayList
The most upvoted question about this seems to have something to do with a problem using an integer as a key, but I think I've avoided that by always using an integer converted to a string. It may be interpreting it strangely, so I'll try some more stuff in the meantime. Thanks for reading!
Alright, figured it out. If anyone reading this has this problem and are using incremented ints/longs/whatever that get converted to strings, you must add some characters to the converted int. Firebase apparently converts these keys back into non-Strings if it can be converted.
For example, if you do something like this:
int inc = 0;
inc++; // 1
map.put(String.valueOf(inc), someList);
Firebase interprets that key as 1 instead of "1".
So, to force Fb to intepret as a string, do something like this:
int inc = 0;
inc++; // 1
map.put(String.valueOf(inc) + "_key", someList);
And everything works out perfectly. Obviously if you also need to read those Strings back to ints, just split the string with "[_]" and you're good to go.
The main issue is that you are using a List instead of a Map. As your error said, while deserializing it is expectig a Map but is found an ArrayList.
So in order to solve this problem youd need to change all the lists in your model with maps like this:
private Map<String, Object> mMapOne;
After changing all those fileds like this, you need also to change your public setters and getters.
Hope it helps.
I am currently working with Java and MySQL, and I found an issue I don't know how to solve.
I have a class that stores a String of 365 positions that represents a Binary String "010111010010100...", and I would like to be able to store and read that field from the database.
Once it is read, I will perform an AND Logic operation with another bitarray.
I read about the BitSet class, that allows the logical operators (AND, OR, XOR, ...) between them. I tried it, but I didn't like the solutions I got. I could also try to transform the String to a byte array, and then store and read it from the database, in order to later perform the logic AND operation, but not sure if I would need to always create a BitSet, and how performant could it be.
I don't know which is the most performant way to do what I want:
Convert the Binary String in another element.
Store that element in the database (in the case of BitSet I tried to define the Database field as BLOB, but I had a lot of issues transforming the BitSet to BLOB and reading the BLOB to a BitSet).
Read the element from the database (at this point would be great to directly work with the element without making any cast or transformation).
Perform a logic AND with another bitarray and get the result.
I have tried a lot of options, but they didn't work.
Could someone help me with this problem and how to better approach it from the performance point of view?
Thanks!
Storing bit in a string is bit weird, I used long to store a number, and make bitwise operations on that. It won't work for you, since you use much more bits. If it can remain string, maybe you can write a short function to make the AND operator on each byte of the string, somehow like this:
for (int i = 0; i<366; i++) {
data .= (stringname[i] == binarystring[i]?"1":"0");
}
Go through your string, while checking if it equals binary string (The one you want to AND it), if they equal, concat 1, if not, concat 0;
I have a byte[] with 3 different objects. How can I read from the byte[] and separate the objects?
My code:
public byte[] toByteArray() {
byte[] bytes;
byte[] sb = start.toString().getBytes();
byte[] gb = goal.toString().getBytes();
byte[] mb = gameBoard.toString().getBytes();
bytes = new byte[sb.length + gb.length + mb.length];
System.arraycopy(sb, 0, bytes, 0, sb.length);
System.arraycopy(gb, 0, bytes, sb.length, gb.length);
System.arraycopy(mb, 0, bytes, gb.length, mb.length);
return bytes;
}
Seems like you are talking about Java not JavaScript.
I recommend you to have a look at binary serialization which I guess is what you are looking for: Saving to binary/serialization java
If you store your data like this, it will be a very difficult task to read them.
I recommend using some build-in object-to-byte[] (and back) conversions like Serializable.
Also, to store several object inside one byte[] array, have a look into ObjectOutputStream
First of all you will need an actual byte[] where stuff can be read from. There are some issues about what you are trying.
toString() usually is not fit to get some data you can reconstruct the object from. It might work with an integer, get a bit messed up with floating point, and be outright impossible with complex objects which only tell about their type and id. (as Davide comment pointed)
There are no cues about where one object starts and ends. Even worse: you might have messed up the start position of 3rd object.
The JRE has a built-in serialization.
Other people use XML or JSON when they need to interact with something else. You might even implement your own flavor of java.text.Format which is able to format and parse your objects. Pick your poison.
I am trying to implement RTSP Server with Java for fun.
Since I do not have any pre-knowledge about RTSP.
I am starting with analysis already made source code.
I found those code in internet.
Link :
http://nsl.cs.sfu.ca/teaching/09/820/streaming/Client.html
http://nsl.cs.sfu.ca/teaching/09/820/streaming/Server.html
http://nsl.cs.sfu.ca/teaching/09/820/streaming/VideoStream.html
http://nsl.cs.sfu.ca/teaching/09/820/streaming/RTPpacket.html
For this posting, I got question about VideoStream.java.
it has a method like below :
public int getnextframe(byte[] frame) throws Exception
{
int length = 0;
String length_string;
byte[] frame_length = new byte[5];
//read current frame length
fis.read(frame_length,0,5);
//transform frame_length to integer
length_string = new String(frame_length);
length = Integer.parseInt(length_string);
return(fis.read(frame,0,length));
}
As you can see, it casts byte[] to String than Integer. However, in my experience, the String turns out a hexa String. So I changed like... below.
Integer.parseInt(length_string.trim(), 16);
It looks OK sometimes, but sometimes gets Number Format Exception.
When I print length_string variables, it show in console like iso2a, vc1mp, 41��� ....
I can not know what I am missing here. Can you explain what is the purpose of codes here?
length_string = new String(frame_length);
length = Integer.parseInt(length_string);
P.S
Is there anyone knows full implementation of these code or other samples which does not uses extra third party libs, it could be much help for me.
I answer to myself to close this question.
Each video types has its own data structure.
In this case, I set data type for 'MJPEG', but I load 'MPEG' file.
So bytes array appears weird way.
FYI, MJPEG is just pack of jpeg. So every frame is key frame.
Other type I handled before, for instance, TS file, has i-frames and b-frames. Former one has clear image since it is key frame. However second one looks broken since it is not a key frame.
I am developing a Java-based downloader for binary data. This data is transferred via a text-based protocol (UU-encoded). For the networking task the netty library is used. The binary data is split by the server into many thousands of small packets and sent to the client (i.e. the Java application).
From netty I receive a ChannelBuffer object every time a new message (data) is received. Now I need to process that data, beside other tasks I need to check the header of the package coming from the server (like the HTTP status line). To do so I call ChannelBuffer.array() to receive a byte[] array. This array I can then convert into a string via new String(byte[]) and easily check (e.g. compare) its content (again, like comparison to the "200" status message in HTTP).
The software I am writing is using multiple threads/connections, so that I receive multiple packets from netty in parallel.
This usually works fine, however, while profiling the application I noticed that when the connection to the server is good and data comes in very fast, then this conversion to the String object seems to be a bottleneck. The CPU usage is close to 100% in such cases, and according to the profiler very much time is spent in calling this String(byte[]) constructor.
I searched for a better way to get from the ChannelBuffer to a String, and noticed the former also has a toString() method. However, that method is even slower than the String(byte[]) constructor.
So my question is: Does anyone of you know a better alternative to achieve what I am doing?
Perhaps you could skip the String conversion entirely? You could have constants holding byte arrays for your comparison values and check array-to-array instead of String-to-String.
Here's some quick code to illustrate. Currently you're doing something like this:
String http200 = "200";
// byte[] -> String conversion happens every time
String input = new String(ChannelBuffer.array());
return input.equals(http200);
Maybe this is faster:
// Ideally only convert String->byte[] once. Store these
// arrays somewhere and look them up instead of recalculating.
final byte[] http200 = "200".getBytes("UTF-8"); // Select the correct charset!
// Input doesn't have to be converted!
byte[] input = ChannelBuffer.array();
return Arrays.equals(input, http200);
Some of the checking you are doing might just look at part of the buffer. If you could use the alternate form of the String constructor:
new String(byteArray, startCol, length)
That might mean a lot less bytes get converted to a string.
Your example of looking for "200" within the message would be an example.
2
You might find that you can use the length of the byte array as a clue. If some messages are long and you are looking for a short one, ignore the long ones and don't convert to characters. Or something like that.
3
Along with what #EricGrunzke said, partially looking in the byte buffer to filter out some messages and find that you don't need to convert them from bytes to characters.
4
If your bytes are ASCII characters, the conversion to characters might be quicker if you use charset "ASCII" instead of whatever the default is for your server:
new String(bytes, "ASCII")
might be faster in that case.
In fact, you might be able to pick and choose the charset for conversion byte-character in some organized fashion that speeds up things.
Depending on what you are trying to do there are a few options:
If you are just trying to get the response status to then can't you just call getStatus()? This would probably be faster than getting the string out.
If you are trying to convert the buffer, then, assuming you know it will be ASCII, which it sounds like you do, then just leave the data as byte[] and convert your UUDecode method to work on a byte[] instead of a String.
The biggest cost of the string conversion is most likely the copying of the data from the byte array to the internal char array of the String, this combined with the conversion is most likely just a bunch of work that you don't need to do.