Solved

Sending A Long in a byte Array

Posted on 2003-11-11
19
555 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
web application structure 18 114
ejb mdb examples 1 21
Need help aligning JRadioButton that put in a box using GridBagLayout 2 27
learn programming 8 70
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

733 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