20

Is there any function equivalent to Python's struct.pack in Java that allows me to pack and unpack values like this?

pump_on = struct.pack("IIHHI", 0, 0, 21, 96, 512)
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
thiruvadi
  • 251
  • 1
  • 3
  • 5

4 Answers4

9

I think what you may be after is a ByteBuffer:

ByteBuffer pump_on_buf = ...
pump_on_buf.putInt(0);
pump_on_buf.putInt(0);
pump_on_buf.putShort(21);
pump_on_buf.putShort(96);
pump_on_buf.putInt(512);
byte[] pump_on = pump_on_buf.array();
SimonC
  • 6,590
  • 1
  • 23
  • 40
  • ByteBuffer doesn't allow you to write Strings, and the contractor requires a buffer size limitation - you need to pre-decide how long your input would be. – Yonatan Apr 16 '13 at 14:10
  • @Yonatan, it does allow you to write strings: `buf.put(s.getBytes())`. `ByteBuffer` requires you to specify the capacity when initially allocating the buffer. Are you saying this is a good thing or a bad thing? – SimonC Apr 19 '13 at 19:43
  • @SimonC ByteBuffer does allow you two write strings in the manner you have shown. However, s.getBytes() will return a UTF-8 encoded byte array from the string (still variable length). It will not have a trailing zero. Beyond that buf.put() uses the current position in the ByteBuffer. This may not be exactly what you want. – Peter Schaeffer Nov 26 '13 at 21:26
4

Something like this:

final ByteArrayOutputStream data = new ByteArrayOutputStream();
final DataOutputStream stream = new DataOutputStream(data);
stream.writeUTF(name);
stream.writeUTF(password);
final byte[] bytes = stream.toByteArray(); // there you go

Later, you can read that data:

final DataInputStream stream = new DataInputStream(
  new ByteArrayInputStream(bytes)
);
final String user = stream.readUTF();
final String password = stream.readUTF();
yegor256
  • 102,010
  • 123
  • 446
  • 597
  • DataOutputStream is good for java primitives only. ObjectOutputStream (which also implements DataOutput interface) gives you ability to write primitives and serializable objects. – Yonatan Apr 16 '13 at 14:13
  • 1
    in this code example it should be `data.toByteArray()` there is no `toByteArray` on DataOutputStream but instead is available on the ByteArrayOutputStream – keios Jul 23 '22 at 14:38
4

I started development of project which is very close to Python Struct: java-binary-block-parser in JBBP it will look like

JBBPOut.BeginBin().Int(0,0).Short(21,96).Int(512).End().toByteArray();
Igor Maznitsa
  • 833
  • 7
  • 12
1

Closest feature in core Java is Serialization. It converts object into byte sequence and back.

Georgy Bolyuba
  • 8,355
  • 7
  • 29
  • 38
  • CAn't believe you. Even as I dislike Java, there should be something closer to being able to do things like this than serialization: Serialization gives you no control on which actual bytes are being created - it just allows you to recreate the same object with those bytes. – jsbueno Jul 09 '10 at 05:08
  • By default it gives you no control, but you can always customize it. Hint: search for readObject/writeObject on the page I gave you a link to. If that is not enough, check out http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/io/Externalizable.html – Georgy Bolyuba Jul 09 '10 at 06:03