2011-11-04 12 views
5

मैं सॉकेट से एक बाइट सरणी में एक स्ट्रिंग जो की तरह लग रहे प्राप्त करते हैं:स्ट्रिंग रूपांतरण के लिए बाइट सरणी में स्ट्रिंग के अंत का पता लगाने के लिए कैसे?

[128,5,6,3,45,0,0,0,0,0] 

आकार नेटवर्क प्रोटोकॉल द्वारा दिए गए मेरे उदाहरण में (शून्य सहित) स्ट्रिंग की कुल लंबाई है हां, तो 10

तो मैं बस कार्य करें:

String myString = new String(myBuffer); 

मैं स्ट्रिंग 5 गैर सही caracter के अंत में है। रूपांतरण स्ट्रिंग कैरेक्टर (0) के अंत का पता लगाने के लिए प्रतीत नहीं होता है।

int sizeLabelTmp = 0; 
//Iterate over the 10 bit to get the real size of the string 
for(int j = 0; j<(sizeLabel); j++) { 
    byte charac = datasRec[j]; 
    if(charac == 0) 
     break; 
    sizeLabelTmp ++; 
} 
// Create a temp byte array to make a correct conversion 
byte[] label = new byte[sizeLabelTmp]; 
for(int j = 0; j<(sizeLabelTmp); j++) { 
    label[j] = datasRec[j]; 
} 
String myString = new String(label); 

वहाँ एक बेहतर तरीका समस्या को संभालने के लिए है:

सही आकार और सही स्ट्रिंग मैं यह नहीं प्राप्त करने के लिए?

धन्यवाद

उत्तर

7

0 "स्ट्रिंग वर्ण का अंत" नहीं है। यह सिर्फ एक बाइट है। चाहे स्ट्रिंग के अंत में यह आता है या नहीं, आप किस एन्कोडिंग का उपयोग कर रहे हैं (और पाठ क्या हो सकता है) पर निर्भर करता है। उदाहरण के लिए, यदि आपने यूटीएफ -16 का उपयोग किया है, तो प्रत्येक अन्य बाइट ASCII वर्णों के लिए 0 होगा।

आप यकीन कि पहले 0 स्ट्रिंग के अंत इंगित करता है, तो आप कोड आपके द्वारा दिए गए जैसे कुछ उपयोग कर सकते हैं, लेकिन मैं के रूप में यह फिर से लिखने चाहते हैं:

int size = 0; 
while (size < data.length) 
{ 
    if (data[size] == 0) 
    { 
     break; 
    } 
    size++; 
} 

// Specify the appropriate encoding as the last argument 
String myString = new String(data, 0, size, "UTF-8"); 

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

यदि आप प्रोटोकॉल के नियंत्रण में हैं, तो यह अधिक बेहतर होगा यदि आप स्ट्रिंग से पहले लम्बा उपसर्ग पेश कर सकते हैं, यह इंगित करने के लिए कि कितने बाइट एन्कोडेड रूप में हैं। इस तरह (बिना "अति-पढ़ने") और आपको बताने के लिए यदि डेटा किसी कारण से काट दिया गया था सक्षम होगा कि वास्तव में आप डेटा की सही मात्रा को पढ़ने में सक्षम हो जाएगा। जावा में

+0

+1 खाते में एन्कोडिंग लेने के लिए +1। यदि सॉकेट पर प्राप्त सामान सिर्फ एक धारावाहिक जावा स्ट्रिंग है तो यह ठीक होना चाहिए। –

+0

@G_H: "बस एक धारावाहिक जावा स्ट्रिंग" वास्तव में निर्दिष्ट नहीं करता है कि धारावाहिक प्रारूप क्या है। यदि ओपी जावा बाइनरी सीरियलाइजेशन का उपयोग कर रहा था तो वह इस ऑपरेशन को स्पष्ट रूप से वैसे भी नहीं कर रहा होगा ... और यदि यह कुछ अन्य धारावाहिक प्रारूप है, तो हमें * * * जानने की आवश्यकता होगी। –

+0

मुझे शायद बात करना बंद कर देना चाहिए ... तथ्य यह है कि, मैंने हमेशा नरक को क्रमबद्धता से दूर रखा है और सभी विवरणों को अच्छी तरह से नहीं जानते हैं। जेएक्सबी या जेपीए आमतौर पर एकमात्र चीज है जिसे मैं एक विकल्प भी मानता हूं। –

2

स्ट्रिंग्स कुछ अन्य भाषाओं में की तरह एक 0 के साथ समाप्त नहीं कर रहे हैं। 0 तथाकथित शून्य चरित्र में बदल जाएगा, जिसे स्ट्रिंग में दिखाई देने की अनुमति है। मेरा सुझाव है कि आप कुछ काट-छाँट योजना है कि या तो सरणी है कि एक 0 है और स्ट्रिंग (सभी बाकी यह सोचते हैं कि बाद 0 हो जाएगा) के निर्माण के लिए, या बस स्ट्रिंग का निर्माण और trim() फोन एक उप सरणी का उपयोग करता है के पहले सूचकांक का पता लगाता है का उपयोग करें। इससे अग्रणी और पिछली सफेद जगह हटा दी जाएगी, जो ASCII कोड 32 या उससे कम के साथ कोई भी चरित्र है।

बाद आप सफेद स्थान को आप की रक्षा करना चाहिए अग्रणी है अगर काम नहीं करेगा। एक स्ट्रिंगबिल्डर का उपयोग करना और अंत में वर्णों को हटा देना जब तक कि वे शून्य चरित्र हैं, उस मामले में बेहतर काम करेंगे।

2

तुम हमेशा बाइट सरणी के अंत में शुरू और पीछे की ओर जाना जब तक आप पहली गैर शून्य हिट कर सकते हैं। फिर बस इसे एक नए बाइट में कॉपी करें और फिर इसे स्ट्रिंग करें। उम्मीद है कि यह मदद करता है:

byte[] foo = {28,6,3,45,0,0,0,0}; 
    int i = foo.length - 1; 

    while (foo[i] == 0) 
    { 
     i--; 
    } 

    byte[] bar = Arrays.copyOf(foo, i+1); 

    String myString = new String(bar, "UTF-8"); 
    System.out.println(myString.length()); 

आपको 4 का परिणाम देगा।

1

ऐसा लगता है कि आप पढ़ने() विधि द्वारा लौटाई गई रीड-गिनती को अनदेखा कर रहे हैं। पीछे की ओर नल बाइट्स शायद नहीं भेजे गए थे, वे शायद बफर की प्रारंभिक स्थिति से अभी भी छोड़ दिए गए हैं।

int count = in.read(buffer); 
if (count < 0) 
    ; // EOS: close the socket etc 
else 
    String s = new String(buffer, 0, count); 
+0

मेरे ओपी में दिखाया गया बफर सिर्फ एक पूरे पैकेट का निकास है। स्ट्रिंग को अन्य डेटा के बीच में भेज दिया जाता है। – grunk

+0

@grunk तो प्रोटोकॉल आपको यह बताना होगा कि यह कितना स्ट्रिंग है, या तो इसे शून्य-टर्मिनिंग या लम्बाई उपसर्ग द्वारा। – EJP

9

बहुत देर हो सकती है, लेकिन यह दूसरों की मदद कर सकती है। सबसे आसान चीज आप कर सकते हैं new String(myBuffer).trim() जो आपको वही देता है जो आप चाहते हैं।

1

मूल ओपी का प्रोटोकॉल विचारों में गोता लगाने के लिए नहीं, पीछे के शून्यों को ट्रिम करने के लिए इसके बारे में कैसे?

public static String bytesToString(byte[] data) { 
    String dataOut = ""; 
    for (int i = 0; i < data.length; i++) { 
     if (data[i] != 0x00) 
      dataOut += (char)data[i]; 
    } 
    return dataOut; 
}