मैं जावा में long
ए byte[]
और बैक को कैसे परिवर्तित करूं ?
मैं एक long
को बदलने की कोशिश कर रहा हूं byte[]
ताकि मैं byte[]
एक टीसीपी कनेक्शन भेज सकूं। दूसरी तरफ मैं byte[]
इसे लेना चाहता हूं और इसे वापस एक में बदल देता हूं double
।
मैं जावा में long
ए byte[]
और बैक को कैसे परिवर्तित करूं ?
मैं एक long
को बदलने की कोशिश कर रहा हूं byte[]
ताकि मैं 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();
}
या बाइटबर्फ बनाने से बचने के लिए एक कक्षा में लिपटे:
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();
}
}
चूंकि यह इतना लोकप्रिय हो रहा है, मैं सिर्फ यह उल्लेख करना चाहता हूं कि मुझे लगता है कि आप अधिकांश मामलों में अमरूद जैसी लाइब्रेरी का उपयोग कर रहे हैं। और यदि आपके पास पुस्तकालयों के लिए कुछ अजीब विरोध है, तो आपको शायद देशी जावा समाधान के लिए पहले इस जवाब पर विचार करना चाहिए । मुझे लगता है कि मुख्य बात यह है कि मेरा जवाब वास्तव में इसके लिए है कि आपको सिस्टम के एंडियन-नेस के बारे में चिंता करने की आवश्यकता नहीं है।
आप Google Guava से बाइट रूपांतरण विधियों का उपयोग कर सकते हैं ।
उदाहरण:
byte[] bytes = Longs.toByteArray(12345L);
मैंने सादे बिटवाइज़ ऑपरेशन के खिलाफ बाइटबफ़र विधि का परीक्षण किया लेकिन बाद में काफी तेज है।
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(final byte[] bytes, final int offset) {
long result = 0;
for (int i = offset; i < Long.BYTES + offset; i++) {
result <<= Long.BYTES;
result |= (bytes[i] & 0xFF);
}
return result;
}
result |= b[i]
बाइट वैल्यू करते हैं तो पहले इसे लंबे समय तक परिवर्तित किया जाएगा जो साइन एक्सटेंशन करता है। मूल्य -128 (हेक्स 0x80
) के साथ एक बाइट मूल्य -128 (हेक्स ) के साथ एक लंबे समय में बदल जाएगा 0xFFFF FFFF FFFF FF80
। रूपांतरण के बाद सबसे पहले मान या: ed एक साथ हैं। बिटवाइज़ का उपयोग करना और पहले से बाइट को एक इंट में बदलना और साइन एक्सटेंशन को काटकर इससे बचाव करना (byte)0x80 & 0xFF ==> (int)0xFFFF FF80 & 0xFF ==> (int) 0x80
:। जावा में बाइट्स क्यों हस्ताक्षर किए जाते हैं यह मेरे लिए थोड़ा रहस्य है, लेकिन मुझे लगता है कि यह अन्य प्रकारों के साथ फिट है।
यदि आप एक तेजी से अनियंत्रित संस्करण की तलाश कर रहे हैं, तो यह चाल करना चाहिए, बाइट सरणी को "बी" कहा जाता है, जिसकी लंबाई 8 है:
बाइट [] -> लंबी
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);
लंबे -> बाइट [] ऊपर के लिए एक सटीक समकक्ष के रूप में
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)};
आपको बाइट की आवश्यकता क्यों है []? सिर्फ सॉकेट के लिए क्यों नहीं लिखा?
मुझे लगता है तुम्हारा मतलब लंबे बजाय लांग , बाद की जरूरत है शून्य मान के लिए अनुमति देने के लिए।
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
dos.writeLong(longValue);
DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();
byte[]
कि अंत करने के लिए सिर्फ एक साधन है।
ByteBuffer
जो डॉक्स के अनुसार "बाइट बफर का प्रारंभिक क्रम हमेशा BIG_ENDIAN है।
बस एक अंतर्निहित ByteArrayOutputStream के साथ DataOutputStream में लंबा लिखें । ByteArrayOutputStream से आप byByteArray () के माध्यम से बाइट-सरणी प्राप्त कर सकते हैं :
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));
}
}
तदनुसार अन्य प्राइमेटिव के लिए काम करता है।
संकेत: टीसीपी के लिए आपको मैन्युअल रूप से बाइट [] की आवश्यकता नहीं है। आप सॉकेट socket
और उसकी धाराओं का उपयोग करेंगे
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 में कर सकते हैं
स्रोत कोड यहाँ है:
लोंग और बाइट्स तरीकों के लिए देखें।
मेरा मानना है कि सॉफ़्टवेयर लाइसेंस आपको कोड के कुछ हिस्सों को लेने और इसका उपयोग करने की अनुमति देता है लेकिन कृपया इसे सत्यापित करें।
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;
}
मैं एक और उत्तर जोड़ूंगा जो सबसे तेज एक संभव yes है (हाँ, स्वीकृत उत्तर से भी अधिक), लेकिन यह हर एक मामले के लिए काम नहीं करेगा। अब, यह हर कल्पनीय परिदृश्य के लिए काम करेगा:
आप बस स्ट्रिंग को मध्यवर्ती के रूप में उपयोग कर सकते हैं। ध्यान दें, यह आपको सही परिणाम देगा, भले ही ऐसा लगता है कि स्ट्रिंग का उपयोग करने से गलत परिणाम मिल सकते हैं, जैसा कि आप जानते हैं कि आप "सामान्य" स्ट्रिंग्स के साथ काम कर रहे हैं। यह प्रभावशीलता बढ़ाने और कोड को सरल बनाने के लिए एक विधि है जिसके बदले में इसके द्वारा संचालित डेटा स्ट्रिंग्स पर कुछ मान्यताओं का उपयोग करना चाहिए।
इस विधि का उपयोग करने का Con: यदि आप ASCII तालिका की शुरुआत में कुछ ASCII वर्णों के साथ इन प्रतीकों की तरह काम कर रहे हैं, तो निम्न पंक्तियाँ विफल हो सकती हैं, लेकिन चलो इसका सामना करते हैं - आप शायद वैसे भी कभी भी इनका उपयोग नहीं करेंगे।
इस विधि का उपयोग करने के प्रो: याद रखें कि अधिकांश लोग आमतौर पर बिना किसी असामान्य चरित्र के कुछ सामान्य तारों के साथ काम करते हैं और फिर विधि सबसे सरल और सबसे तेज़ तरीका है।
लंबे से बाइट तक []:
byte[] arr = String.valueOf(longVar).getBytes();
बाइट से [] तक:
long longVar = Long.valueOf(new String(byteArr)).longValue();
यदि आप 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 प्राप्त पक्ष पर।
ByteBuffer.allocate (8) .putLong (obj) .अरे () के साथ।
public byte[] toBytes(Long obj) {
if (obj != null) {
return ByteBuffer.allocate(8).putLong(obj).array();
return null;
}
स्रोत:
ByteBuffer के कई अन्य उपयोग उदाहरणों के लिए:
यहाँ जावा 8 या नए का उपयोग करने के लिए परिवर्तित byte[]
करने long
का एक और तरीका है :
private static int bytesToInt(final byte[] bytes, final int offset) {
assert offset + Integer.BYTES <= bytes.length;
return (bytes[offset + Integer.BYTES - 1] & 0xFF) |
(bytes[offset + Integer.BYTES - 2] & 0xFF) << Byte.SIZE |
(bytes[offset + Integer.BYTES - 3] & 0xFF) << Byte.SIZE * 2 |
(bytes[offset + Integer.BYTES - 4] & 0xFF) << Byte.SIZE * 3;
}
private static long bytesToLong(final byte[] bytes, final int offset) {
return toUnsignedLong(bytesToInt(bytes, offset)) << Integer.SIZE |
toUnsignedLong(bytesToInt(bytes, offset + Integer.BYTES));
}
परिवर्तित long
करने को दो-पूर्णांक मानों के उच्च और निम्न-क्रम बिट्स के रूप में व्यक्त किया जा सकता है जो एक बिटवाइज़-ओआर के अधीन हैं। ध्यान दें कि toUnsignedLong
से है Integer
वर्ग और करने के लिए पहली कॉल toUnsignedLong
ज़रूरत से ज़्यादा हो सकता है।
विपरीत रूपांतरण को अनियंत्रित किया जा सकता है, जैसा कि दूसरों ने उल्लेख किया है।
लंबे और बाइट के लिए कोटलीन एक्सटेंशन प्रकार:
fun Long.toByteArray() = numberToByteArray(Long.SIZE_BYTES) { putLong(this@toByteArray) }
private inline fun numberToByteArray(size: Int, bufferFun: ByteBuffer.() -> ByteBuffer): ByteArray =
ByteBuffer.allocate(size).bufferFun().array()
@Throws(NumberFormatException::class)
fun ByteArray.toLong(): Long = toNumeric(Long.SIZE_BYTES) { long }
@Throws(NumberFormatException::class)
private inline fun <reified T: Number> ByteArray.toNumeric(size: Int, bufferFun: ByteBuffer.() -> T): T {
if (this.size != size) throw NumberFormatException("${T::class.java.simpleName} value must contains $size bytes")
return ByteBuffer.wrap(this).bufferFun()
}
आप मेरी लाइब्रेरी https://github.com/ArtemBotnev/low-level-extensions में पूरा कोड देख सकते हैं