Longをbyte []に変換し、Javaに戻すにはどうすればよいですか? TCP接続でbyte []を送信できるように、longをbyte []に変換しようとしています。反対側では、そのbyte []を取得してdoubleに変換したいです。任意のヒントをいただければ幸いです。
public byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}
public long bytesToLong(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong();
}
または、ByteBufferを繰り返し作成しないようにクラスにラップします。
public class ByteUtils {
private static ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
public static byte[] longToBytes(long x) {
buffer.putLong(0, x);
return buffer.array();
}
public static long bytesToLong(byte[] bytes) {
buffer.put(bytes, 0, bytes.length);
buffer.flip();//need flip
return buffer.getLong();
}
}
これは非常に人気が高まっているので、ほとんどの場合にGuavaのようなライブラリを使用した方が良いと思います。ライブラリに奇妙な反対がある場合は、おそらくネイティブJavaソリューションについて この回答 を最初に検討する必要があります。私の答えが実際に行っている主なことは、システムのエンディアン性について自分で心配する必要がないということです。
ByteBufferメソッドを単純なビット単位の操作に対してテストしましたが、後者の方がはるかに高速です。
public static byte[] longToBytes(long l) {
byte[] result = new byte[8];
for (int i = 7; i >= 0; i--) {
result[i] = (byte)(l & 0xFF);
l >>= 8;
}
return result;
}
public static long bytesToLong(byte[] b) {
long result = 0;
for (int i = 0; i < 8; i++) {
result <<= 8;
result |= (b[i] & 0xFF);
}
return result;
}
なぜbyte []が必要なのですか?ソケットに書き込むだけではどうですか?
Longではなくlongを意味すると仮定します。後者はnull値を許可する必要があります。
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
dos.writeLong(longValue);
DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();
高速の展開バージョンを探している場合は、長さ8の「b」というバイト配列を想定して、これでうまくいくはずです。
byte []-> long
long l = ((long) b[7] << 56)
| ((long) b[6] & 0xff) << 48
| ((long) b[5] & 0xff) << 40
| ((long) b[4] & 0xff) << 32
| ((long) b[3] & 0xff) << 24
| ((long) b[2] & 0xff) << 16
| ((long) b[1] & 0xff) << 8
| ((long) b[0] & 0xff);
long-> byte []上記の正確な対応物として
byte[] b = new byte[] {
(byte) lng,
(byte) (lng >> 8),
(byte) (lng >> 16),
(byte) (lng >> 24),
(byte) (lng >> 32),
(byte) (lng >> 40),
(byte) (lng >> 48),
(byte) (lng >> 56)};
基礎となる ByteArrayOutputStream で DataOutputStream にlongを書き込むだけです。 ByteArrayOutputStreamから toByteArray() を使用してバイト配列を取得できます。
class Main
{
public static byte[] long2byte(long l) throws IOException
{
ByteArrayOutputStream baos=new ByteArrayOutputStream(Long.SIZE/8);
DataOutputStream dos=new DataOutputStream(baos);
dos.writeLong(l);
byte[] result=baos.toByteArray();
dos.close();
return result;
}
public static long byte2long(byte[] b) throws IOException
{
ByteArrayInputStream baos=new ByteArrayInputStream(b);
DataInputStream dos=new DataInputStream(baos);
long result=dos.readLong();
dos.close();
return result;
}
public static void main (String[] args) throws Java.lang.Exception
{
long l=123456L;
byte[] b=long2byte(l);
System.out.println(l+": "+byte2long(b));
}
}
それに応じて他のプリミティブで機能します。
ヒント:TCPの場合、byte []は手動で必要ありません。 Socketsocket
とそのストリームを使用します
OutputStream os=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeLong(l);
//etc ..
代わりに。
Org.Apache.hadoop.hbase.util.Bytesの実装を使用できます http://hbase.Apache.org/apidocs/org/Apache/hadoop/hbase/util/Bytes.html
ソースコードは次のとおりです。
ToLongおよびtoBytesメソッドを探します。
ソフトウェアライセンスにより、コードの一部を取得して使用することができますが、確認してください。
public static long bytesToLong(byte[] bytes) {
if (bytes.length > 8) {
throw new IllegalMethodParameterException("byte should not be more than 8 bytes");
}
long r = 0;
for (int i = 0; i < bytes.length; i++) {
r = r << 8;
r += bytes[i];
}
return r;
}
public static byte[] longToBytes(long l) {
ArrayList<Byte> bytes = new ArrayList<Byte>();
while (l != 0) {
bytes.add((byte) (l % (0xff + 1)));
l = l >> 8;
}
byte[] bytesp = new byte[bytes.size()];
for (int i = bytes.size() - 1, j = 0; i >= 0; i--, j++) {
bytesp[j] = bytes.get(i);
}
return bytesp;
}
既にOutputStream
を使用してソケットに書き込む場合は、 DataOutputStream が適している可能性があります。以下に例を示します。
// Assumes you are currently working with a SocketOutputStream.
SocketOutputStream outputStream = ...
long longValue = ...
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeLong(longValue);
dataOutputStream.flush();
short
、int
、float
などにも同様のメソッドがあります。受信側で DataInputStream を使用できます。
最速の1つである別の回答を追加しますye(はい、受け入れられている回答よりもさらに多くなります)ですが、すべてのケースで機能するわけではありません。ただし、考えられるすべてのシナリオで機能します。
単に文字列を中間として使用できます。 「通常の」文字列を使用している限り、Stringを使用すると誤った結果が生じるように思われる場合でも、正しい結果が得られます。これは、有効性を高め、コードを単純化する方法です。コードを単純化するためには、操作対象のデータ文字列に何らかの仮定を使用する必要があります。
この方法の使用の賛成: ASCIIテーブルの先頭でこれらの記号のようないくつかのASCII文字を使用している場合、次の行が失敗する可能性があります、しかしそれに直面しましょう-とにかくそれらを使用することはないでしょう。
このメソッドを使用することの長所:ほとんどの人は通常、通常とは異なる文字を使用せずに通常の文字列を操作することを忘れないでください。
longからbyte []まで:
byte[] arr = String.valueOf(longVar).getBytes();
byte []からLongまで:
long longVar = Long.valueOf(new String(byteArr)).longValue();