जावा में एक स्ट्रिंग के बाइट्स


179

जावा में, अगर मेरे पास एक स्ट्रिंग है, तो मैं xउस स्ट्रिंग में बाइट्स की संख्या की गणना कैसे कर सकता हूं?


15
एक HTTP प्रतिक्रिया के शरीर का प्रतिनिधित्व करने के लिए एक स्ट्रिंग का उपयोग करना चाहते हैं और "सामग्री-लंबाई" हेडर सेट करने के लिए आकार का उपयोग कर सकते हैं, जो ऑक्टेट / बाइट्स वर्णों में निर्दिष्ट है। w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
iX3

4
डेटाबेस डेटाबेस में बाइट्स में लंबाई प्रतिबंध हो सकता है, उदाहरण के लिए Oracle में VARCHAR2 (4000 BYTE)। एक वांछित स्ट्रिंग में स्ट्रिंग का बाइट काउंट जानना चाह सकता है ताकि पता चल सके कि स्ट्रिंग फिट होगा।
सोमू

@ iX3 बिल्कुल वैसा ही जैसा मैं करने की कोशिश कर रहा था।
एमसी सम्राट

1
मेरा मानना ​​है कि इस सवाल की दो संभावित व्याख्याएं हैं, इरादे पर निर्भर करता है: एक यह है कि "मेरे स्ट्रिंग उपयोग में कितनी मेमोरी है?"। इसका उत्तर नीचे दिए गए @roozbeh द्वारा प्रदान किया गया है (शायद संकुचित OOPS जैसी modulo VM सूक्ष्मताएं)। दूसरा है, "अगर मैं स्ट्रिंग को बाइट में परिवर्तित करता हूं [] तो बाइट सरणी का कितना मेमोरी उपयोग करेगा?"। यह सवाल है जिसका जवाब आंद्रेज डॉयल ने दिया है। अंतर बड़ा हो सकता है: UTF8 में "हैलो वर्ल्ड" 11 बाइट्स है, लेकिन स्ट्रिंग (प्रति @roozbeh) 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()। और यह मानने के चक्कर में न पड़ें कि UTF-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 "????")

(ध्यान दें कि यदि आप वर्ण सेट तर्क प्रदान नहीं करते हैं, तो प्लेटफ़ॉर्म का डिफ़ॉल्ट वर्ण सेट उपयोग किया जाता है। यह कुछ संदर्भों में उपयोगी हो सकता है, लेकिन सामान्य रूप से आपको चूक के आधार पर बचना चाहिए, और एन्कोडिंग / जब हमेशा स्पष्ट वर्ण सेट का उपयोग करें डिकोडिंग की आवश्यकता है।)


1
तो फिर से अगर मैं getBytes () का उपयोग करता हूं। यह मुझे x के समान लंबाई देगा। मैं गलत हूं क्योंकि मुझे यकीन नहीं है
ग्रीन

4
@Green ऐश बाइट सरणी की लंबाई - getBytes () - और x.length MAY के बराबर होनी चाहिए लेकिन ऐसा होने की गारंटी नहीं है। यह समान होगा यदि सभी वर्णों को एक-एक बाइट द्वारा दर्शाया जाए। यह हमेशा चरित्र एनकोडिंग के लिए सही रहेगा, जो प्रति चरित्र (या उससे कम) एकल बाइट का उपयोग करता है, जैसे ISO-8859-1। UTF-8 1 या 2 बाइट्स का उपयोग करता है, इसलिए यह स्ट्रिंग में सटीक वर्णों पर निर्भर करता है। फिर चरित्र एनकोडिंग हैं जो हमेशा प्रति चरित्र दो बाइट्स का उपयोग करते हैं।
क्रिस

मुझे आपका उत्तर पसंद है :), इसलिए वे किसी भी तरह एक ही हो सकते हैं लेकिन हमेशा मैं सही नहीं हूं? ठीक है, तो पैरामीटर के बिना विधि का उपयोग करना ठीक है क्योंकि यह मेरे लिए त्रुटि पैदा करता है !!
ग्रीन

@ बात यह है कि बाइट्स की संख्या हमेशा वर्णों की संख्या के समान नहीं होती है । बाइट्स की संख्या उपयोग किए जाने वाले वर्ण एन्कोडिंग पर निर्भर करती है। आपको यह जानना होगा कि आप किस चरित्र एन्कोडिंग का उपयोग करने जा रहे हैं और इसे ध्यान में रखें। आप क्या त्रुटि प्राप्त कर रहे हैं? यदि आप getBytes()इसका उपयोग करते हैं तो यह आपके सिस्टम के डिफ़ॉल्ट चरित्र एन्कोडिंग का उपयोग करेगा।
जेसपर

1
@KorayTugay हां, कम या ज्यादा। आप कारण और प्रभाव के क्रम के बारे में बहस कर सकते हैं, हालांकि। मैं यह बताना चाहूंगा कि एक चर हमेशा 2 बाइट्स होता है क्योंकि यह एक आदिम डेटा प्रकार है जिसे 2 बाइट्स के रूप में परिभाषित किया गया है। (और यह कि UTF-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-बिट VM या 64-बिट VM पर संपीड़ित OOPs (-XX: + UseCompressedOops) के साथ, संदर्भ 4 बाइट्स हैं। तो कुल होगा:

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

यह स्ट्रिंग ऑब्जेक्ट के संदर्भों को ध्यान में नहीं रखता है।


6
मैं यह मान रहा था कि प्रश्न एक स्ट्रिंग ऑब्जेक्ट के लिए मेमोरी में आवंटित बाइट्स की संख्या के बारे में था। यदि प्रश्न स्ट्रिंग को क्रमबद्ध करने के लिए आवश्यक बाइट्स की संख्या के बारे में है, जैसा कि अन्य ने बताया है, यह उपयोग किए गए एन्कोडिंग पर निर्भर करता है।
रोजोजेब

2
उर उत्तर के लिए स्रोत? धन्यवाद
Mavis

1
नोट: 14 sizeofसे अधिक होना चाहिए
डायटर

19

पांडित्य का उत्तर (हालांकि जरूरी नहीं कि सबसे उपयोगी एक हो, जो इस बात पर निर्भर करता है कि आप परिणाम के साथ क्या करना चाहते हैं):

string.length() * 2

जावा स्ट्रिंग्स को UTF-16BEएन्कोडिंग में भौतिक रूप से संग्रहीत किया जाता है , जो प्रति कोड यूनिट 2 बाइट्स का उपयोग करता है, और String.length()UTF-16 कोड इकाइयों में लंबाई को मापता है, इसलिए यह इसके बराबर है:

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

और यह आपको बाइट्सchar में आंतरिक सरणी का आकार बताएगा ।

नोट: पूर्व एन्कोडिंग BOM सम्मिलित करने "UTF-16"से भिन्न परिणाम "UTF-16BE"देगा , सरणी की लंबाई में 2 बाइट जोड़ देगा ।


रूजबेह का जवाब बेहतर है, क्योंकि यह अन्य बाइट्स को भी ध्यान में रखता है।
लोदीविजक बोगार्ड्स

@finnw क्या आप सुनिश्चित हैं कि एन्कोडिंग UTF-16BE है और UTF-16 नहीं है? स्ट्रिंग क्लास Javadoc ( docs.oracle.com/javase/6/docs/api/java/lang/String.html ) के अनुसार, "एक स्ट्रिंग UTF-16 प्रारूप में एक स्ट्रिंग का प्रतिनिधित्व करता है ..."।
entpnerd

17

जावा में UTF8 बाइट सरणियों से स्ट्रिंग्स को कैसे और कैसे परिवर्तित करें :

String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);

लेकिन मुझे माफ करना जब मैं आपके कोड को संकलित करता हूं तो यह मुझे एक त्रुटि देता है; पैरामीटर "UTF-8" के कारण। जब मैं एक खाली पैरामीटर पास करता हूं तो यह मुझे x.length के समान लंबाई देता है। मैं अवधारणा को गलत समझता हूं। कृपया मदद करें
हरे रंग की

@Green ऐश, आपके पास जावा का कौन सा संस्करण है?
बुआके सिंडी

@ग्रीन ऐश, आपको क्या अपवाद मिल रहे हैं?
बुहाके सिंडी

2
स्पष्ट होना यह आउटपुट है: test.java:11: unreported अपवाद java.io.UnsupportedEncodingException; पकड़ा जाना चाहिए या बाइट फेंकने की घोषणा की जानी चाहिए [] b = s.getBytes ("UTF-8"); ^ 1 त्रुटि प्रक्रिया पूरी हुई।
हरा रंग

3
@ग्रीन, कोशिश करें s.getBytes(Charset.forName("UTF-8")):।
james.garriss

10

एक Stringउदाहरण मेमोरी में एक निश्चित मात्रा में बाइट्स आवंटित करता है। हो सकता है कि आप कुछ ऐसा देख रहे हों, sizeof("Hello World")जो डेटास्ट्रक्चर द्वारा आवंटित बाइट्स की संख्या को वापस कर देगा?

जावा में, आमतौर पर किसी sizeofफ़ंक्शन की आवश्यकता नहीं होती है , क्योंकि हम डेटा संरचना को संग्रहीत करने के लिए मेमोरी आवंटित नहीं करते हैं। हम String.javaएक मोटे अनुमान के लिए फ़ाइल पर एक नज़र डाल सकते हैं , और हम कुछ 'इंट', कुछ संदर्भ और ए देखते हैं char[]जावा भाषा विनिर्देश परिभाषित करता है, एक है कि char0 से 65535 तक का पर्वतमाला है, तो दो बाइट्स स्मृति में एक भी चार रखने के लिए पर्याप्त हैं। लेकिन एक जेवीएम को 2 बाइट्स में एक चार को स्टोर करने की आवश्यकता नहीं है, यह केवल गारंटी देने के लिए है, कि कार्यान्वयन charडिफाइन रेंज के मूल्यों को पकड़ सकता है।

तो sizeofवास्तव में जावा में कोई मतलब नहीं है। लेकिन, यह मानते हुए कि हमारे पास एक बड़ी स्ट्रिंग है और एक charदो बाइट्स आवंटित करता है, तो किसी Stringऑब्जेक्ट की मेमोरी फ़ुटप्रिंट कम से कम 2 * str.length()बाइट्स में है।


7

वहाँ एक विधि getBytes () कहा जाता है । समझदारी से इस्तेमाल करो ।


17
बुद्धिमानी = एक चरित्र सेट पैरामीटर के बिना एक का उपयोग न करें।
थिलो

क्यों? क्या यह एक समस्या है अगर मैं UTF8 एन्कोडिंग के साथ चलने के लिए अपने वातावरण को कॉन्फ़िगर करता हूं?
जिग्गी

1
getBytes भी बाइट्स के एरे को बनाएंगे और कॉपी करेंगे, इसलिए यदि आप लंबी स्ट्रिंग्स की बात कर रहे हैं, तो यह ऑपरेशन काफी महंगा हो सकता है।
टिकटॉक

@ticktock, यदि आप अभी भी आस-पास हैं, हाँ, लेकिन विकल्प क्या है? मुझे यहां लाइब्रेरी फंक्शन की उम्मीद थी जो स्टोरेज को वापस करने की जरूरत थी, इसलिए मैं इसे एक बड़े आवंटन में जोड़ सकता हूं।
सेंसरसमिथ

4

इसे इस्तेमाल करे :

Bytes.toBytes(x).length

आपने पहले घोषित एक्स और आरंभिक मान लिया


3
क्या यह मानक जावा लाइब्रेरी का हिस्सा है? मुझे Bytesकक्षा नहीं मिल रही है ।
Kröw

0

कोशिश पकड़ने से बचने के लिए, उपयोग करें:

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);
System.out.println(b.length);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.