Solved

Sending A Long in a byte Array

Posted on 2003-11-11
19
550 Views
Last Modified: 2010-03-31
I am trying to send a Long value that represents a filesize into a 128 byte data packet, the first byte is a header then I have reserved the next 8 bytes for the filesize.

I have done some research and found a class called BigInteger
http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html
that does this.

My problem is knowing how many of the bytes to read back off at the other side, as If I read all 8 on a long value that doesnt fill all 8 then I get a wrong value, here is my code.

-------------
//Create Byte array and append to packet
     BigInteger big = new BigInteger(Long.toString(fileLength));
     byte[] testlong = new byte[8];
     testlong =  big.toByteArray();
     String dickString = new String(testlong);
     System.out.println(big.longValue() );//test to see if its seding the right value

     //Copy to the packet
     System.arraycopy(testlong, 0, testbuffer, 1, 8);
     // I get an arrayindex Out Of Bounds error here




------------
//Read from packet

     byte[] fileSize = new byte[8];
     //read back the 8 bytes from the data packet
     System.arraycopy(testbuffer, 1, fileSize, 0, 8);
     BigInteger big2 = new BigInteger(fileSize);
     System.out.println(big2.longValue() );


I can get it working with a small number eg 352, but I have to use 2 bytes instead of 8 to avoid the outofbounds exception.


Appreciate any help
0
Comment
Question by:welsh_boy
  • 9
  • 7
  • 3
19 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 9726216
Try

BigInteger big = new BigInteger.valueOf(fileLength);
     testlong =  big.toByteArray();
     System.out.println(big.longValue() );//test to see if its seding the right value
     //Copy to the packet
     System.arraycopy(testlong, 0, testbuffer, 0, 8);
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9726226
Sorry:

     BigInteger big = new BigInteger.valueOf(fileLength);
     byte[] testlong =  big.toByteArray();
     System.out.println(big.longValue() );//test to see if its sending the right value
     //Copy to the packet
     System.arraycopy(testlong, 0, testbuffer, 0, 8);
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9726253
LOL, and the second index should be 1, not 0 (just saw the thing about the header). Make sure testbuffer.length >= 9
0
 
LVL 92

Expert Comment

by:objects
ID: 9726294
Use of BigInteger is a bit slow and unecessary.

You can use bit manipulation to handle converting bytes into long.
Here's an example of how to convert 4 bytes into an int, doing it for a long is a simple extension:
      int ch1 = buf[0]
      int ch2 = buf[1];
      int ch3 = buf[2];
      int ch4 = buf[3];
                int = return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

Or alternatively use a DataInputStream wrapping a ByteArrayInputStream to handle it for you:

DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf));
long l = in.readLong();
0
 
LVL 92

Expert Comment

by:objects
ID: 9726307
Similiar techniques can also be used for going the other direction.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9726367
It's only slow if it's perceptibly slow - and it almost certainly won't be. It's certainly more elegant and clearer.
0
 
LVL 92

Expert Comment

by:objects
ID: 9726440
More elegant and clear than:

long l = in.readLong();

I don't think so :)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9726459
I was talking about your first suggestion
0
 

Author Comment

by:welsh_boy
ID: 9726465
Here is my ammended code, I am still getting the error

--

//Declare the Data Packet
      byte [] testbuffer=new byte [128];
//Set Header
        testbuffer[0]=PacketCode.SFT;
//Copy File name at byte[9]
      System.arraycopy(tester, 0, testbuffer, 9, tester.length);



     BigInteger big = new BigInteger(Long.toString(fileLength));
     byte[] testlong =  big.toByteArray();
     System.out.println("Long Send to Packet : " + big.longValue() );//test to see if its sending the right value
     //Copy to the packet at position 1 - 8
     System.arraycopy(testlong, 0, testbuffer, 1, 8); //<-- I get an out of bounds error here
     
     
//Read back long from the packet array

//Set up and empty 8 byte array
     byte[] fileSize = new byte[8];
//Copy long back from the byte array pos 1-8
     System.arraycopy(testbuffer, 1, fileSize, 0, 8);
     BigInteger big2 = new BigInteger(fileSize);
     System.out.println("Read Long from Data Packet: " + big2.longValue() );
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 92

Expert Comment

by:objects
ID: 9726500
DataOuputStream out = new DataOutputStream(new ByteArrayOutputStream(128));
out.writeByte(PacketCode.SFT);
out.writeLong(fileLength);
out.write(tester);
byte [] testbuffer= out.toByteArray();
0
 
LVL 92

Expert Comment

by:objects
ID: 9726515
And reading it back:

DataInputStream in = new DataInputStream(new ByteArrayInputStream(testbuffer));
byte packet = in.readByte();
long fileLength = in.readLong();
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 50 total points
ID: 9726590
>>//<-- I get an out of bounds error here

Are you perhaps reassigning testbuffer to another array reference in the mean time?

Check the lengths of

testlong
testbuffer
0
 
LVL 92

Expert Comment

by:objects
ID: 9726691
> byte[] testlong =  big.toByteArray();

This will not necessarily return an 8 byte buffer. If you want to use this approach you will need to do:

System.arraycopy(testlong, 0, testbuffer, 1, testlong.length);
0
 
LVL 92

Expert Comment

by:objects
ID: 9726708
Actually thats not right either, should be:

System.arraycopy(testlong, 0, testbuffer, 1+(8-testlong.length), testlong.length);

Lot simpler to use DataOutput :)
0
 

Author Comment

by:welsh_boy
ID: 9726710
cheers objects but the DataOutputStream doesnt seem to have a toByteArray() method
Im running Java 1.31

I have looked for the javadocs
http://java.sun.com/j2se/1.3/ja/docs/ja/api/java/io/DataOutputStream.html

any ideas??
0
 
LVL 92

Assisted Solution

by:objects
objects earned 200 total points
ID: 9726751
Oops, my fault. That methods on the underlying ByteArrayOutputStream.

ByteArrayOutputStream bout = new ByteArrayOutputStream(128);
DataOuputStream out = new DataOutputStream(bout);
out.writeByte(PacketCode.SFT);
out.writeLong(fileLength);
out.write(tester);
byte [] testbuffer= bout.toByteArray();
0
 

Author Comment

by:welsh_boy
ID: 9726809
thanks objects an CEHJ

Decided to go with the DataOuputStream method, It is a lot more efficient

Thanks for the lesson!
0
 
LVL 92

Expert Comment

by:objects
ID: 9726821
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9730507
>>Decided to go with the DataOuputStream method, It is a lot more efficient

I agree. And objects is right about the toByteArray method of BigInteger: if there are leading zeros in the long, they won't be represented by empty array elements - they'll simply be omitted. There really should be a toLongByteArray method or something returning all 8 bytes.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now