2011-06-30 14 views
5

'dan hem metin hem de ikili verileri okuyun İkili bir akıştan veri okumaya çalışıyorum, bunun kısımları UTF-8 olarak ayrıştırılmalıdır. KullanılmasıInputStream

doğrudan ikili veri için InputStream ve maksimum okumak için söylendi olsa bile okuyucu öncesinde okuyup pisliği sonraki ikili veri gibi çalışmıyor UTF-8 metin için bunun üstüne bir InputStreamReadern karakterden oluşuyor.

Bu sorunun Read from InputStream in multiple formats'a çok benzediğini biliyorum, ancak önerilen çözüm, HTTP akışlarına özeldir, bu bana yardımcı olmuyor.

Her şeyi sadece ikili veri olarak okuyup ilgili parçaları metne dönüştürmeyi düşündüm. Ama sadece karakter verilerinin uzunluk bilgisini, bayt cinsinden değil, karakterlerde var. Böylece, kodlamanın farkında olmak için akıştan karakterleri okuyan şeylere ihtiyacım var.

InputStreamReader'a, belirtilen karakter sayısını okumak için gerekenden fazlasını okumaya söylememesinin bir yolu var mı? Ya da bir kodlama ile hem ikili verileri hem de metni destekleyen bir okuyucu var ve bu modlar arasında anında geçiş yapılabilir mi?

cevap

2

Önce ikili bölümleri okumalısınız. UTF-8 kod çözme işlemine ihtiyaç duyan baytların bir kısmını tanıdığınızda, bu baytları ayıklayıp kod çözmeniz gerekir.

DataInputStream dis = 
// read a binary type. 
int num = dis.readInt(); 
int len = dis.readUnsignedShort(); 
// read a UTF-8 portion. 
byte[] bytes = new byte[len]; 
dis.readFully(bytes); 
String text = new String(bytes, "UTF-8"); 
// read some binary 
double d = dis.readDouble(); 
+1

Sorun, UTF8 ile, bayt sayısı karakter sayısından farklı olabilir. Bu yüzden dizede çok baytlı karakterlerin sayısını bulmalı, daha fazla bayt oku ve tekrar çevirmeli ve sayılar eşleşene kadar bunu tekrar etmem gerek. – tajmahal

+0

Biçimlendirmenizin kodunu çözmeyi çok kolay olmadığını söyleyebilirim ve yapabiliyorsanız bunu düzeltirim. Ancak, karakter sayısını biliyorsanız, UTF-8'i kendiniz ayrıştırabilirsiniz. (Ancak gerçek sayı baytlarını göndermek çok daha kolay olurdu) –

+0

Başka bir yaklaşım, ihtiyaç duyulandan daha fazla veri okumaktır. Beklenen karakterlerin sayısını al, ör. substring() ve uzunluğu belirlemek için UTF-8'e dönüştürülür. İşaretle() ve sıfırla() kullanarak ve şimdi bildiğiniz uzunluğu okuyun. (Bu sadece UTF-8 kodlaması tam olarak aynıysa çalışır: | nul bayt \ 0, iki farklı yolla kodlanır.(diğer karakterler olabileceği gibi) –

2

Sadece StreamReader kullanmamalısınız. Okuyucular metinle uğraşırlar, ancak metin ve ikili veriyi birlikte ele alırsınız.

Bunun bir yolu yoktur. İkili arabellekleri okumanız ve formatınızı kendiniz yorumlamalısınız, yani metin çıktısı baytının konumunu bulun ve bunları String'e dönüştürmelisiniz.

Bu görevi basitleştirmek için kendi sınıfınızı oluşturmanızı öneririz (diyelim ki ProtocolRecord.) Bu, Seri hale getirilebilir olmalıdır. Tüm alanlarınızı içerecektir. Artık 2 seçeneğiniz var:

(1) basit bir - java serileştirme mekanizmasını kullanın. Bu durumda, akışınızı sadece okuma için DataInputStream ve yazmak için DataOutputStream ile sarmanız ve ardından nesnelerinizi okuyup yazmanız gerekir. Bu yaklaşımın dezavantajı, protokolünüzü kontrol edememenizdir.

(2) readObject() ve writeObject() yöntemlerini kendiniz uygulayabilirsiniz. Şimdi DataInputStream ve DataOutputStream'i yukarıda açıklandığı gibi kullanın. Bu durumda, serileştirme protokolünü uygulamak zorundasınız, ancak en azından sınıfınıza kapsüllenmiş.

DataInputStream'in ihtiyacınız olan şey olduğunu düşünün.

İlgili konular