2014-09-19 10 views
8

İçinde kodlanmış bir dizenin uzunluğu nedir? Yukarıdaki kod satırı neden yazdırıyor 12, bunun yerine 11 yazdırılmalı mı?Bir ByteBuffer

+0

olduğu belgeleri okuyor. –

+0

Ben get ve put yöntemleri kullanmak zorunda kalmadan, destek dizisine herkese açık erişime sahip olduğunuzu şaşırıyorum. – azurefrog

cevap

11

dizinin uzunluğu ByteBuffer boyutudur ' kodlama yaptığınız karakter sayısına eşittir, ancak bunlardan eşit değildir. Eğer encode() yöntem haline inerseniz

, sen CharsetEncoder#encode(CharBuffer) şuna benzer olduğunu göreceksiniz ... en bir ByteBuffer için bellek ayrılamadı nasıl bir göz atalım: my ayıklayıcıya göre

public final ByteBuffer encode(CharBuffer in) 
    throws CharacterCodingException 
{ 
    int n = (int)(in.remaining() * averageBytesPerChar()); 
    ByteBuffer out = ByteBuffer.allocate(n); 
    ... 

, UTF_8$Encoder'un averageBytesPerChar değeri 1.1 ve String girdisi 11 karakterleri içerir. 11 * 1.1 = 12.1 ve kod hesaplama yapar bir int için toplam atan, yani ByteBuffer Sonuçta ortaya çıkan bu üzerinden ağ dikkatli bir şekilde ilk olmadan ByteBuffer.array yöntemi kullanma için şüpheli 12.

+5

Vay canına, bu ortağa kimin çıkacağını ve hangi veri kümesini kullandıklarını merak ediyorum.Her nasılsa, kafasını fırında ve ayaklarını dondurucuda tutan istatistikçiyle ilgili şakayı hatırlatıyor ve kendini ortalama olarak rahat bir şekilde sıcak olarak ilan ediyor. –

1

ByteBuffer döndürür. Bu, arabelleğin kapasite (gerçekten olası dilimlemeden dolayı bile değil), kaç bayt kullanıldığını değil. malloc(10)'un 32 bayt belleğe geri dönüşü ücretsizdir.

System.out.println(Charset.forName("UTF-8").encode("hello world").limit()); 

Bu 11 (beklendiği gibi).

+0

Sanmıyorum. Boş bir dizi oluşturduysanız, bir şey için varsayılan olur ve ödevden sonra kullanılan bayt sayısından daha yüksek olabilirdi, ancak bu durumda, kopya kurucusu çağrılır ve dizinin başlatılacağını beklerdim. iletilen karakter sayısı. – ventsyv

+0

Bir dizi oluşturduğunuzda, '.length' için istediğiniz uzunluk (Java özelliğindedir) olacaktır. Bu durumda, 'encode()', ne yapacağını söylemez, sadece 'ByteBuffer' için istediğiniz kodlanmış karakterleri döndürür. Diğerleri içine kazandılar ve bu bir uygulama detayı, bu nedenle bu davranış JVM sürümleri ve uygulamaları arasında farklılık gösterecek. –

+0

Tamam, bu mantıklı. – ventsyv

0
import java.nio.charset.*; 
public class ByteArrayTest { 
    public static void main(String[] args) { 
     String theString = "hello world"; 
     System.out.println(theString.length()); 
     byte[] byteArray = Charset.forName("UTF-8").encode(theString).array(); 
     System.out.println(byteArray.length); 
     for (int i = 0; i < byteArray.length; i++) { 
      System.out.println("Byte " + i + " = " + byteArray[i]); 
     } 
    } 
} 

Sonuçlar: iyi bir Cı-dize olacak gibi

C:\JavaTools>java ByteArrayTest 
11 
12 
Byte 0 = 104 
Byte 1 = 101 
Byte 2 = 108 
Byte 3 = 108 
Byte 4 = 111 
Byte 5 = 32 
Byte 6 = 119 
Byte 7 = 111 
Byte 8 = 114 
Byte 9 = 108 
Byte 10 = 100 
Byte 11 = 0 

dizi boş sonlandırılmış.

(Ama görünüşe göre gerçek nedeni pul pul yöntem array. Muhtemelen büyük bir özenle dışında "üretim" kodunda kullanılmamalıdır. Olduğu)

+3

0 bayt sondaki boş bir sonlandırıcı – Andreas

+0

@Andreas - Yep kadar büyük olduğunu sanmıyorum, muhtemelen haklısınız - [dizi] (http://docs.oracle.com/javase/7 /docs/api/java/nio/ByteBuffer.html#array%28%29), ByteBuffer'in iç arabelleğini döndüren yarı-sahte bir işlemdir ve bu nedenle ne kadar büyük olacağını söyleyemezsiniz. –

+0

@Andreas: Java çalışma zamanı (tahmin edeyim) C cinsinden uygulanmıştır, bu yüzden dizelerin süresiz olarak sonlandırılması uygun olabilir. :-) –

İlgili konular