জাভাতে একটি স্ট্রিংয়ের বাইট


179

জাভাতে, আমার কাছে স্ট্রিং থাকলে আমি xকীভাবে সেই স্ট্রিংয়ের বাইটের সংখ্যা গণনা করতে পারি?


15
কেউ এইচটিটিপি প্রতিক্রিয়াটির মূল প্রতিনিধিত্ব করতে স্ট্রিং ব্যবহার করতে এবং "সামগ্রী-দৈর্ঘ্য" শিরোনামটি সেট করতে মাপ ব্যবহার করতে পারেন, যা অক্ষরে নয় অষ্টে / বাইটে উল্লিখিত হয়েছে। w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
iX3

4
একটি ডাটাবেস কলামে বাইটের দৈর্ঘ্যের সীমাবদ্ধতা থাকতে পারে, যেমন ওরাকল-এ VARCHAR2 (4000 BYTE)। স্ট্রিংটি উপযুক্ত কিনা তা জানতে কাঙ্ক্ষিত এনকোডিংয়ে স্ট্রিংয়ের বাইট গণনাটি জানতে চাইতে পারেন know
সোমু

@ iX3 ঠিক যেমনটি আমি করার চেষ্টা করছিলাম ঠিক তেমনই।
এমসির সম্রাট

1
আমি বিশ্বাস করি উদ্দেশ্যটির উপর নির্ভর করে এই প্রশ্নের দুটি সম্ভাব্য ব্যাখ্যা রয়েছে: একটি হ'ল "আমার স্ট্রিংটি কত স্মৃতি ব্যবহার করে?" এর উত্তর নীচে @ রূজ্বেহ দ্বারা সরবরাহ করা হয়েছে (সংক্ষিপ্ত ওওপিএসের মতো মডুলো ভিএম সূক্ষ্মতা)। অন্যটি হ'ল, "আমি যদি স্ট্রিংটিকে একটি বাইটে রূপান্তর করি [] সেই বাইট অ্যারে কত স্মৃতি ব্যবহার করবে?" এটি এমনই প্রশ্নের উত্তর যা আন্দ্রেজেজ ডয়েলে উত্তর দিয়েছেন। পার্থক্যটি বড় হতে পারে: ইউটিএফ 8-তে "হ্যালো ওয়ার্ল্ড" 11 বাইট, তবে স্ট্রিং (প্রতি @ রূজবেহ) 50 বাইট (যদি আমার গণিতটি ঠিক থাকে)।
এল ব্ল্যাঙ্ক

আমার যুক্ত করা উচিত ছিল যে 11 বাইটগুলিতে বাইট [] যা তাদের ধারণ করে তার ওভারহেড অন্তর্ভুক্ত করে না তাই তুলনাটি কিছুটা বিভ্রান্তিকর।
এল ব্ল্যাঙ্ক

উত্তর:


289

একটি স্ট্রিং হল অক্ষরের একটি তালিকা (যেমন কোড পয়েন্ট)। স্ট্রিংটি উপস্থাপন করতে নেওয়া বাইটের সংখ্যা পুরোপুরি নির্ভর করে যে আপনি কোন এনকোডিংটি এটিকে বাইটে পরিণত করার জন্য ব্যবহার করেন

এটি বলেছিল, আপনি স্ট্রিংটিকে একটি বাইট অ্যারেতে পরিণত করতে পারেন এবং তার আকারটি নীচের দিকে দেখতে পারেন:

// The input string for this test
final String string = "Hello World";

// Check length, in characters
System.out.println(string.length()); // prints "11"

// Check encoded sizes
final byte[] utf8Bytes = string.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "11"

final byte[] utf16Bytes= string.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "24"

final byte[] utf32Bytes = string.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "44"

final byte[] isoBytes = string.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "11"

final byte[] winBytes = string.getBytes("CP1252");
System.out.println(winBytes.length); // prints "11"

সুতরাং আপনি দেখতে পাচ্ছেন, এমনকি কোনও সাধারণ "এএসসিআইআই" স্ট্রিংয়ের উপস্থাপনায় বিভিন্ন সংখ্যক বাইট থাকতে পারে যা নির্ভর করে কোন এনকোডিং ব্যবহৃত হয়। যুক্তি হিসাবে আপনার কেসের জন্য আপনি যে কোনও চরিত্র সেট করতে আগ্রহী তা ব্যবহার করুন getBytes()। এবং ধরে নেওয়ার ফাঁদে পড়বেন না যে ইউটিএফ -8 প্রতিটি চরিত্রকে একক বাইট হিসাবে উপস্থাপন করে , কারণ এটিও সত্য নয়:

final String interesting = "\uF93D\uF936\uF949\uF942"; // Chinese ideograms

// Check length, in characters
System.out.println(interesting.length()); // prints "4"

// Check encoded sizes
final byte[] utf8Bytes = interesting.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "12"

final byte[] utf16Bytes= interesting.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "10"

final byte[] utf32Bytes = interesting.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "16"

final byte[] isoBytes = interesting.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "4" (probably encoded "????")

final byte[] winBytes = interesting.getBytes("CP1252");
System.out.println(winBytes.length); // prints "4" (probably encoded "????")

(মনে রাখবেন যে আপনি যদি কোনও অক্ষর সেট যুক্তি সরবরাহ না করেন তবে প্ল্যাটফর্মের ডিফল্ট অক্ষর সেটটি ব্যবহার করা হবে some এটি কিছু প্রেক্ষাপটে কার্যকর হতে পারে তবে সাধারণভাবে আপনার ডিফল্টের উপর নির্ভর করে এড়ানো উচিত এবং এনকোডিং করার সময় সর্বদা একটি স্পষ্ট অক্ষর সেট ব্যবহার করা উচিত / ডিকোডিং প্রয়োজনীয়)


1
সুতরাং আমি যদি আবার গেটবাইটস () ব্যবহার করি তবে এটি আমাকে দৈর্ঘ্যের মতো x. দৈর্ঘ্য কি আমি ভুল কারণ আমি নিশ্চিত নই
সবুজ

4
@ গ্রিন অ্যাশ বাইট অ্যারের দৈর্ঘ্য - গেটবাইটস () - এবং x. দৈর্ঘ্য হতে পারে সমান তবে এটির গ্যারান্টি নেই। এটি সমান হবে যদি সমস্ত অক্ষর প্রতিটি একক বাইট দ্বারা উপস্থাপন করা হয়। এটি অক্ষর এনকোডিংগুলির ক্ষেত্রে সর্বদা সত্যই থাকবে যা ISO-8859-1 এর মতো অক্ষর প্রতি একক বাইট (বা কম) ব্যবহার করে। ইউটিএফ -8 1 বা 2 বাইট ব্যবহার করে, তাই এটি স্ট্রিংয়ের সঠিক অক্ষরের উপর নির্ভর করে। তারপরে অক্ষর এনকোডিংগুলি রয়েছে যা সর্বদা অক্ষর প্রতি দুটি বাইট ব্যবহার করে।
ক্রিস

আমি আপনার উত্তরটি পছন্দ করি :), তাই তারা কোনওভাবে একরকম হতে পারে তবে সবসময় আমি ঠিক না? ঠিক আছে তবে প্যারামিটার ছাড়াই পদ্ধতিটি ব্যবহার করা ঠিক কি কারণ এটি আমার জন্য ত্রুটি ঘটায় !!
সবুজ

@ গ্রিন পয়েন্টটি হ'ল বাইট সংখ্যা সর্বদা অক্ষরের সংখ্যার মতো হয় না । বাইটের সংখ্যা ব্যবহৃত অক্ষর এনকোডিংয়ের উপর নির্ভর করে। আপনি জানতে হবে যে কোন অক্ষর এনকোডিং আপনি ব্যবহার করতে যাচ্ছেন এবং তা অ্যাকাউন্টে নেবেন। আপনি কি ত্রুটি পাচ্ছেন? আপনি যদি এটি ব্যবহার করেন তবে getBytes()এটি আপনার সিস্টেমের ডিফল্ট অক্ষর এনকোডিং ব্যবহার করবে।
জেস্পার

1
@ KorayTugay হ্যাঁ, কম বা কম। যদিও আপনি কারণ এবং প্রভাবের ক্রম সম্পর্কে তর্ক করতে পারেন। আমি আরও জানাতে চাই যে একটি চরটি সর্বদা 2 বাইট হয় কারণ এটি একটি আদিম ডাটা টাইপ যা 2 বাইট প্রশস্ত বলে সংজ্ঞায়িত করা হয়। (এবং ইউটিএফ -16 প্রতিনিধিত্ব মূলত এটির অন্য ফলাফলের চেয়ে বরং একটি পরিণতি ছিল))
আন্দ্রেজেজ ডয়েল

63

আপনি যদি 64৪-বিট রেফারেন্স সহ চালাচ্ছেন:

sizeof(string) = 
8 + // object header used by the VM
8 + // 64-bit reference to char array (value)
8 + string.length() * 2 + // character array itself (object header + 16-bit chars)
4 + // offset integer
4 + // count integer
4 + // cached hash code

অন্য কথায়:

sizeof(string) = 36 + string.length() * 2

একটি 32-বিট ভিএম বা সংক্ষিপ্ত ওওপিএস (-XX: + UseCompPressOops) সহ একটি 64-বিট ভিএম-এ, রেফারেন্সগুলি 4 বাইট। সুতরাং মোট হবে:

sizeof(string) = 32 + string.length() * 2

এটি স্ট্রিং অবজেক্টের রেফারেন্সগুলিকে বিবেচনা করে না।


6
আমি ধরে নিচ্ছিলাম যে প্রশ্নটি একটি স্ট্রিং অবজেক্টের জন্য মেমরিতে বরাদ্দকৃত বাইটের সংখ্যা সম্পর্কে ছিল। যদি প্রশ্নটি স্ট্রিংকে সিরিয়ালায়িত করতে প্রয়োজনীয় বাইটের সংখ্যা সম্পর্কে হয়, যেমন অন্যরা উল্লেখ করেছেন, এটি ব্যবহৃত এনকোডিংয়ের উপর নির্ভর করে।
রোজবিহ

2
আপনার উত্তর জন্য উত্স? ধন্যবাদ
ম্যাভিস

1
দ্রষ্টব্য: sizeof8 এর একাধিক হওয়া উচিত
ডাইটার

19

পেডেন্টিক উত্তর (যদিও আপনি ফলটি নিয়ে কী করতে চান তার উপর নির্ভর করে সর্বাধিক দরকারী একটি নয়) হ'ল:

string.length() * 2

জাভা স্ট্রিংগুলি শারীরিকভাবে UTF-16BEএনকোডিংয়ে সংরক্ষণ করা হয় , যা প্রতিটি কোড ইউনিটে 2 বাইট ব্যবহার String.length()করে এবং ইউটিএফ -16 কোড ইউনিটে দৈর্ঘ্য পরিমাপ করে, তাই এটি সমান:

final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);

এবং এটি আপনাকে অভ্যন্তরীণ charঅ্যারের আকার , বাইটে জানাবে ।

দ্রষ্টব্য: প্রাক্তন এনকোডিংটি একটি বিওএম sert োকানো হবে , অ্যারের দৈর্ঘ্যে 2 বাইট যুক্ত করে "UTF-16"একটি আলাদা ফলাফল "UTF-16BE"দেবে ।


রুজবহের উত্তর আরও ভাল, কারণ এটি অন্যান্য বাইটগুলিও বিবেচনায় নিয়েছে।
লোডেভিজক বোগার্ডস

@ ফিনউ আপনি কি নিশ্চিত যে এনকোডিংটি ইউটিএফ -16 বিই এবং ইউটিএফ -16 নয়? স্ট্রিং ক্লাস জাভাদোক ( docs.oracle.com/javase/6/docs/api/java/lang/String.html ) অনুসারে, "একটি স্ট্রিং ইউটিএফ -16 ফর্ম্যাটে একটি স্ট্রিং উপস্থাপন করে ..."।
এন্টার্নার্ড

17

তবে আমি যখন আপনার কোডটি সংকলন করি তখন এটি আমাকে ত্রুটি দেয়; "ইউটিএফ -8" প্যারামিটারের কারণেই where যেখানেই আমি খালি প্যারামিটারটি পাস করি এটি আমার দৈর্ঘ্যটি x. দৈর্ঘ্যের হিসাবে দেয়। আমি ধারণা ভুল বুঝি। সাহায্য করুন
সবুজ

@ গ্রীন অ্যাশ, আপনার জাভাটির কোন সংস্করণ আছে?
বুহাকে সিন্ধি

@ গ্রীন অ্যাশ, আপনি কী ব্যতিক্রম পাচ্ছেন?
বুহাকে সিন্ধি

2
পরিষ্কার হওয়ার জন্য এটি আউটপুট: test.java:11: অপরিবর্তিত ব্যতিক্রম java.io.UnsupportedEncodingException; অবশ্যই ধরা হবে বা বাইট ফেলে দেওয়া হবে [] b = s.getBytes ("ইউটিএফ -8"); Error 1 ত্রুটি প্রক্রিয়া শেষ হয়েছে।
সবুজ

3
@Green, চেষ্টা করে দেখুন: s.getBytes(Charset.forName("UTF-8"))
james.garriss

10

একটি Stringউদাহরণ মেমরিতে একটি নির্দিষ্ট পরিমাণ বাইট বরাদ্দ করে। হয়তো আপনি এরকম কিছু খুঁজছেনsizeof("Hello World") কিছুর যা নিজেই ডেটাস্ট্রাকচার দ্বারা বরাদ্দকৃত বাইটের সংখ্যাটি ফিরিয়ে দেবে?

জাভাতে সাধারণত কোনও sizeofফাংশনের প্রয়োজন হয় না , কারণ আমরা কখনই ডেটা স্ট্রাকচার সঞ্চয় করার জন্য মেমরি বরাদ্দ করি না। আমরা কটাক্ষপাত থাকতে পারে String.javaএকটা মোটামুটি প্রাক্কলন জন্য ফাইল, এবং আমরা কিছু 'int- এ', কিছু রেফারেন্স এবং একটি দেখতে char[]জাভা ল্যাঙ্গুএজ স্পেসিফিকেশন সংজ্ঞায়িত, একটি যে char0 থেকে 65535 রেঞ্জের, তাই দুই বাইট মেমরি একটি একক গৃহস্থালির কাজ রাখার যথেষ্ট। তবে একটি জেভিএমকে 2 বাইটে একটি চর সংরক্ষণ করতে হবে না, এটি কেবল গ্যারান্টি দিতে হবে, এটি বাস্তবায়নেরchar নির্ধারিত পরিসরের মান ধরে রাখতে পারে।

সুতরাং sizeofজাভা কোন সত্যিকার অর্থে না। তবে, ধরে নিই যে আমাদের একটি বড় স্ট্রিং রয়েছে এবং একটিতে charদুটি বাইট বরাদ্দ করা হয়, তবে কোনও Stringবস্তুর মেমরির পদচিহ্ন কমপক্ষে 2 * str.length()বাইটে থাকে।


7

গেটবাইটস () নামে একটি পদ্ধতি রয়েছে । এটি বুদ্ধিমানের সাথে ব্যবহার করুন।


17
বুদ্ধিমানের সাথে = অক্ষর সেট পরামিতি ব্যতীত এটিকে ব্যবহার করবেন না।
থিলো

কেন? আমি যদি ইউটিএফ 8 এনকোডিংয়ের সাথে চালানোর জন্য আমার পরিবেশটি কনফিগার করি তবে এটি কি একটি সমস্যা?
জিগি

1
গেটবাইটস বাইটের অ্যারেও তৈরি করবে এবং অনুলিপি করবে, সুতরাং আপনি যদি দীর্ঘ স্ট্রিংয়ের কথা বলছেন তবে এই ক্রিয়াকলাপটি মূল্যবান হতে পারে।
ticktock

@ টিকটক, আপনি যদি এখনও আশেপাশে থাকেন তবে হ্যাঁ তবে বিকল্পটি কী? প্রয়োজনীয় স্টোরেজটি ফিরিয়ে আনার জন্য আমি একটি লাইব্রেরি ফাংশন আশা করে এখানে এসেছি যাতে আমি এটিকে আরও বড় বরাদ্দে একত্রিত করতে পারি।
সেন্সরসমিত

4

এটা চেষ্টা কর :

Bytes.toBytes(x).length

ধরে নিয়েছি আপনি এক্স এর আগে ঘোষিত এবং আরম্ভ করেছেন


3
এটি কি স্ট্যান্ডার্ড জাভা লাইব্রেরির অংশ? আমি Bytesক্লাস খুঁজে পাচ্ছি না ।
ক্রু

0

ধরার চেষ্টা এড়াতে, ব্যবহার করুন:

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);
System.out.println(b.length);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.