আমি কীভাবে জাভাতে 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();
}
}
যেহেতু এটি এত জনপ্রিয় হয়ে উঠছে, আমি কেবল উল্লেখ করতে চাই যে আমি মনে করি আপনি বেশিরভাগ ক্ষেত্রে গুয়ারা জাতীয় লাইব্রেরি ব্যবহার করা ভাল off এবং আপনার যদি গ্রন্থাগারগুলির বিরুদ্ধে কিছু অদ্ভুত বিরোধিতা থাকে, তবে সম্ভবত সম্ভবত দেশীয় জাভা সমাধানের জন্য আপনার এই উত্তরটি বিবেচনা করা উচিত । আমি মনে করি যে আমার উত্তরটি সত্যই এটির পক্ষে গেছে তা হ'ল আপনাকে নিজেরাই সিস্টেমের এন্ডিয়ান-নেস সম্পর্কে চিন্তা করতে হবে না।
আপনি গুগল পেয়ারা থেকে বাইট রূপান্তর পদ্ধতি ব্যবহার করতে পারেন ।
উদাহরণ:
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
। রূপান্তর হওয়ার পরে প্রথমে মানগুলি বা: এড একসাথে হয়। , Bitwise-এবং ব্যবহার এই বিরুদ্ধে প্রথম সাইন এক্সটেনশানটি বন্ধ কোন int এবং কাটা করতে বাইট রূপান্তর দ্বারা রক্ষা করে: (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 হয়
অন্তর্নিহিত বাইটআর্যআউটপুট স্ট্রিম সহ একটি ডেটাআউটপুট স্ট্রিমটিতে কেবল দীর্ঘ লিখুন । বাইটআর্যআউটপুট স্ট্রিম থেকে আপনি টু বাইটআরে () এর মাধ্যমে বাইট-অ্যারে পেতে পারেন :
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;
}
আমি আরও একটি উত্তর যুক্ত করব যা দ্রুততম সম্ভব ׂ (হ্যাঁ, স্বীকৃত উত্তরের চেয়েও বেশি), তবে এটি প্রতিটি একক ক্ষেত্রে কার্যকর হবে না। যাইহোক, এটি প্রতিটি কল্পনাপ্রসূত দৃশ্যের জন্য কাজ করবে:
আপনি কেবল স্ট্রিংকে মধ্যবর্তী হিসাবে ব্যবহার করতে পারেন। দ্রষ্টব্য, এটি আপনাকে সঠিক ফলাফল দেবে, যদিও মনে হচ্ছে স্ট্রিং ব্যবহারের ফলে ভুল ফলাফল হতে পারে আপনি দীর্ঘমেয়াদে জানেন যে আপনি "সাধারণ" STRING এর সাথে কাজ করছেন। কার্যকারিতা বাড়াতে এবং কোডটিকে আরও সহজ করার জন্য এটি এমন একটি পদ্ধতি যা এর পরিবর্তে ডেটা স্ট্রিংয়ের উপর চালিত ডেটা স্ট্রিংগুলির জন্য কিছু অনুমান ব্যবহার করা উচিত।
এই পদ্ধতিটি ব্যবহার করার বিষয়টি: আপনি যদি ASCII সারণির শুরুতে এই চিহ্নগুলির মতো কিছু ASCII অক্ষরের সাথে কাজ করছেন তবে নিম্নলিখিত লাইনগুলি ব্যর্থ হতে পারে তবে আসুন এটির মুখোমুখি হন - আপনি সম্ভবত এগুলি কখনও ব্যবহার করবেন না।
এই পদ্ধতিটি ব্যবহারের প্রো: মনে রাখবেন যে বেশিরভাগ লোকেরা সাধারণত কোনও অস্বাভাবিক চরিত্র ছাড়াই কিছু সাধারণ স্ট্রিং নিয়ে কাজ করেন এবং তারপরে পদ্ধতিটি যাওয়ার সহজতম এবং দ্রুততম উপায়।
দীর্ঘ থেকে বাইট []:
byte[] arr = String.valueOf(longVar).getBytes();
বাইট [] থেকে দীর্ঘ পর্যন্ত:
long longVar = Long.valueOf(new String(byteArr)).longValue();
আপনি যদি ইতিমধ্যে OutputStream
সকেটে লিখতে একটি ব্যবহার করছেন, তবে ডেটাআউটপুট স্ট্রিমটি ভাল ফিট হতে পারে। এখানে একটি উদাহরণ:
// 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 প্রাপ্তির দিকে।
বাইটবফার.লোকট (8) সাথে .পুটলং (আপত্তি) .আরে ()
public byte[] toBytes(Long obj) {
if (obj != null) {
return ByteBuffer.allocate(8).putLong(obj).array();
return null;
}
উৎস:
বাইটবফারের অন্যান্য অনেক ব্যবহারের উদাহরণের জন্য:
জাভা 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 এ সম্পূর্ণ কোড দেখতে পারেন