It's not a secret anymore!*
The moose likes Java in General and the fly likes convert long to byte array and back Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "convert long to byte array and back" Watch "convert long to byte array and back" New topic
Author

convert long to byte array and back

reinout korbee
Greenhorn

Joined: Dec 17, 2005
Posts: 2
I want to store a long in a byte array, transfer it over a network, then convert it back to a long. I do this:

and then back:

But this only works for integers, even though I use longs or cast to longs. How is this possible? How do I get my long back?
Scott Johnson
Ranch Hand

Joined: Aug 24, 2005
Posts: 518
In Java, a long is 8 bytes not 4.
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Why reinvent the wheel? The wrapper classes such as java.lang.Long provide a byteValue() method to get it as a byte and the java.lang.Byte wrapper provides longValue(), intValue(), etc. methods to convert back. I've never had reason to use these so I apologize if it's a stupid suggestion.
Maximilian Xavier Stocker
Ranch Hand

Joined: Sep 20, 2005
Posts: 381
Originally posted by Ken Blair:
Why reinvent the wheel? The wrapper classes such as java.lang.Long provide a byteValue() method to get it as a byte and the java.lang.Byte wrapper provides longValue(), intValue(), etc. methods to convert back. I've never had reason to use these so I apologize if it's a stupid suggestion.


Those methods are of some use but not for this. From the API byteValue of Long

"the numeric value represented by this object after conversion to type byte."

The keyword there being conversion. So you are turning an 8 byte number into 1 byte number and as such losing 7 bytes worth of data.

As the previous poster mentioned longs are 8 bytes not 4. A useful class to look at is java.io.DataInputStream which has methods for creating primitives from bytes.

For example for readLong


Which as you can see uses readInt which in turns reads each byte and does it's think with them.

Anyway the DataInputStream and DataOutputStream classes give you full working source for all the primitive conversions. But in fact you don't have to do it on your own at all.

If you want to store primitives as bytes like that do this...



and basically everything flipped to read it back in....

Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Use the java.nio buffers for this kind of data conversion.


Tony Morris
Java Q&A (FAQ, Trivia)
Maximilian Xavier Stocker
Ranch Hand

Joined: Sep 20, 2005
Posts: 381
Originally posted by Tony Morris:
Use the java.nio buffers for this kind of data conversion.


Why would that be better than using java.io.DataInputStream for this purpose?
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
I actually wondered how it could convert a long which is greater than one byte to a single byte, but I guess I assumed the lack of a toByteArray() or equivalent meant that it must be able to convert them somehow.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Maximilian]: Why would that be better than using java.io.DataInputStream for this purpose?

Generally using NIO can lead to significantly better performance. Though in some cases there's no difference - and occasionally the performance is worse. More to the point though, most people seem to find the NIO classes harder to understand than the IO classes. Especially for people new to NIO, or to IO for that matter. If Reinout is currently using IO classes, the simplest solution will probably be to use a DataOutputStream, sticking with IO classes. But if the performance needs improvement, it may be helpful to replace most (or all) of the IO classes with NIO classes.


"I'm not back." - Bill Harding, Twister
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
I took a long look at many questions like this, and found this post... I didn't like the fact that the conversion code is duplicated for each type, so I've made a generic method to perform the task:



See full post
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7526
    
  18

Adam Zehavi wrote:...so I've made a generic method to perform the task:...

Any reason why you've revived a 7-year old thread to tell us this?

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Adam Zehavi wrote:I took a long look at many questions like this, and found this post... I didn't like the fact that the conversion code is duplicated for each type, so I've made a generic method to perform the task:



See full post



As already mentioned (in this 7 year old topic), what would be the purpose of reinventing the wheel? Why can't you just use a ByteBuffer?



Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
7 or 15 does not matter it can always be of some service, I've looked this up because I needed it, and I got closer to the answer on this page.

Plus, in my case I needed to have this conversion on both Java and Embedded C, so that is why
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37950
    
  22
Welcome to the Ranch

That method almost certainly contains a serious error in the bit about n-1*8, I am afraid.
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
That method almost certainly contains a serious error in the bit about n-1*8, I am afraid.


Ha Ha.... I missed that one...
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2988
    
    9
A "generic method" means something different in Java. But it looks like you're trying to make a method that takes an undocumented parameter "n" that means... ummm... maybe the number of bytes? Which presumably will not ever be greater than 8? Ok, I suppose that could be used to reduce code duplication compared to the code from the page you cited (whose methods look extremely similar to what's in DataInputStream and DataOutputStream, of course). But if you're reducing duplication, why not put it in a loop? Don't you need a loop anyway so that your result has only n bytes? Why not show actual working code here?

I would guess, however, that the evil duplicated code you're replacing is actually faster, and that's probably why DataInputStream and DataOutputStream were written as they were. Duplication isn't always evil, especially if it's compact and easy to understand, and it's encapsulated in a library where most people will never need to look at it; they just use it.
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
I was trying to keep the answer in the spirit of the question, and what I was looking for, all together, that is why I didn't add the loop.
As for performance, I take performance very seriously when it comes to large numbers of iterations, over a short period of time, then I would most defiantly use a faster method, but in my case/s I need a once in every 1-4 seconds to perform that conversion, so it doesn't really matter... in any case the final method looks like this, I know this is not very efficient, right now I'm more into generic(write once utilize for many NOT real Java Generic types):

Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2988
    
    9
Cool, thanks for clarifying.

One thing about library code is that, although it's usually a bad idea to optimize prematurely, the fact that many different people may use a method can mean that someone, somewhere actually does use that method in a tight loop repeated many times, and actually does benefit from it being faster. So widely-used library code has more reason to be optimized than code that only a few people use.
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
Agreed... Will add some docs to mention these facts!
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7526
    
  18

Adam Zehavi wrote:I take performance very seriously...

Then you might be interested to know that
Class<? extends Number> dataType = data.getClass();
if (dataType == Byte.class) {...

takes about 8 times as long as
if (dataType instanceof Byte) {...
(at least on my computer)...and the latter handles nulls.

Sometimes the simplest is the best.

Winston
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37950
    
  22
Aren’t the wrapper classes all final? The instanceof operator is much more reliable with final classes.
But don’t the Wrapper classes all have a static SIZE field which records the number of bits used? You can use that with << 3 to convert the bits to bytes. That may hit problems with BigDecimal and BigInteger which extend Number but don’t have the SIZE field.
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
Winston Gutkowski wrote:
Adam Zehavi wrote:I take performance very seriously...

Then you might be interested to know that
Class<? extends Number> dataType = data.getClass();
if (dataType == Byte.class) {...

takes about 8 times as long as
if (dataType instanceof Byte) {...
(at least on my computer)...and the latter handles nulls.


WOW... I'm new here and already liking it...
To be honest I've never checked this one out, I've been told at the beginning of my carrier that the opposite is true and I've taken it like a fool.

After simulating on my computer I've came with the following results:

equals 1000000 iterations duration: 78, 51, 59, 45, 47, 47 ms
instanceof 1000000 iterations duration: 43, 39, 51, 42, 43, 45 ms

I've called on the method I've posted earlier, once with '==' and once with instanceof.

Thanks for the input...
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
Campbell Ritchie wrote:
But don’t the Wrapper classes all have a static SIZE field which records the number of bits used? You can use that with << 3 to convert the bits to bytes.

That may hit problems with BigDecimal and BigInteger which extend Number but don’t have the SIZE field.


I don't follow?
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2988
    
    9
I'm confused too. Looks like Adam is already using the SIZE field, and whether he uses (Long.SIZE / Byte.SIZE) or (Long.SIZE >> 3) doesn't make much difference; it's a compile-time constant anyway. I would argue the former is more readable. The SIZE field would be more useful if we could make use of it without knowing what particular class the data is an instance of - but I don't see how to do that without reflection, e.g.

That might minimize code reuse, but is probably even slower - and as Campbell notes, will have problems if Data is a BigInteger or BigDecimal, or AtomicInteger or AtomicLong or other subclass without a SIZE.
Adam Zehavi
Greenhorn

Joined: Jun 03, 2012
Posts: 11
Some results:

equals 1000000 iterations duration: 284
equals <<3 1000000 iterations duration: 243
instanceof 1000000 iterations duration: 248

instanceof <<3 1000000 iterations duration: 206

And it keeps coming this way... where the bold ones race...
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37950
    
  22
Mike Simmons wrote:I'm confused too. Looks like Adam is already using the SIZE . . .
Yes, I missed that. Sorry
 
 
subject: convert long to byte array and back
 
Similar Threads
can we store an integer in a byte array
Conversion Long to byte[]
Byte to long
Byte order conversion question
Quick String to <char> Array Conversion