2013-04-03 15 views
5

Sokete yazmak istiyorum. BufferedWriter önerilir OutputStreamWriter girdi tampon ediyorumBufferedWriter ve BufferedOutputStream birlikte kullanmak aşırı mı?

OutputStream outs=null; 
BufferedWriter out=null; 
out = 
    new BufferedWriter(
    new OutputStreamWriter(new BufferedOutputStream(outs),"UTF-8")); 

o yazar önlediğinden,: ağ IO hakkında okumasını, böyle bir şey yapmak olduğunu en iyi yolu yazmak için geliyor bana her karakter için kodlayıcıyı başlatma. , baytları ağa bir kerede bir bayt koymaktan kaçınmak için baytları arabelleğe alır.

Biraz overkill gibi görünüyor, ama hepsi yardımcı oluyor gibi görünüyor? herhangi bir yardım sükranla ..

DÜZENLEME: OutputStreamWriter üzerine javadoc kaynaktan:

bir yazma Her bir çağırma() metodu kodlayan dönüştürücü belirli bir karakter (ler) üzerinde çağrılır neden olur. Sonuçtaki baytlar, temel çıktı akışına yazılmadan önce bir tamponda biriktirilir. Bu arabelleğin boyutu belirtilebilir, ancak varsayılan olarak çoğu amaç için yeterince büyüktür. Write() yöntemlerine iletilen karakterlerin arabelleğe alınmadığını unutmayın.

En yüksek verimlilik için, sık sık dönüştürücü çağrışımlarından kaçınmak için bir BufferedWriter içinde bir OutputStreamWriter sarmayı düşünün. BufferedWriter her bir karakter için kodlayıcı başlatılmasından yazar önlediği için önerilir OutputStreamWriter girdi tampon olacaktır

Writer out = new BufferedWriter(new OutputStreamWriter(System.out)); 

cevap

1

: Örneğin.

Kim tarafından ve hangi bağlamda önerilir? "Enkoder başlatılıyor" ile ne demek istiyorsun? Bir keresinde yazarın tek bir karakterini yazıyor musun? (Size yazar nasıl kullandığınızı ... bu önemli olabilir hakkında çok şey bilmiyorum.)

BufferedOutputStream sonra Writer gelen bayt tampon olacaktır üzerine potansiyel bir seferde bir bayt koyarak önlemek için ağ

Her seferinde bir bayt yazabileceğini düşündüren nedir? OutputStreamWriter'un, o anda bir karakteri gerçekten yazmazsanız, alttaki yazara bir bayt yazması pek olası değildir. Ayrıca, ağ çıkış akışının tek baytlı paketler göndermekten kaçınmak için Nagle's algorithm gibi bir şey kullanmasını beklerdim. Üste |

Optimizasyon ile birlikte olduğu gibi, bunu kanıtlara göre yapmalısınız ... bu tamponlama katmanlarıyla birlikte ve bunlar olmadan herhangi bir test yaptınız mı?

DÜZENLEME: Sadece açıklığa kavuşturmak için, arabellek sınıflarının işe yaramaz olduğunu söylemiyorum. Bazı durumlarda, kesinlikle gitmek için doğru yollardır. Ben sadece tüm optimizasyon gibi, onlar kör olarak kullanılmamalıdır. Ne için optimize etmeye çalıştığınızı (işlemci kullanımı, bellek kullanımı, ağ kullanımı vb.) Ve ölçütü dikkate almalısınız.Burada önemli olan pek çok faktör vardır - en azında yazma şekli vardır. Zaten "chunkily" yazıyorsanız - büyük karakter veri blokları yazıyorsanız, bu durumda tamponlar nispeten az bir etkiye sahip olacaktır. Yazara bir kerede tek bir karakter yazıyorsanız, daha anlamlı olurlar.

+0

Cevabınız için teşekkür ederiz. OutputStreamWriter üzerindeki javadoc'tan, "Write() yönteminin her bir komutu, kodlama dönüştürücüsünün belirtilen karakter (ler) üzerinde çalıştırılmasına neden olur. Sonuçtaki baytlar, temel çıktı akışına yazılmadan önce bir tamponda biriktirilir. Bu arabellek belirtilebilir, ancak varsayılan olarak çoğu amaç için yeterince büyüktür. write() yöntemlerine iletilen karakterlerin arabelleğe alınmadığını unutmayın. En yüksek verim için, bir Sıkıştırılmış Yazıcı içinde bir OutputStreamWriter'ı sık dönüştürücü çağrılarından kaçınmak için sarmalamayı düşünün. ." OP etiketindeki tüm alıntılar – Bruce

+0

@Bruce: * Düşün *, elbette. Bu, * ile * aynı değildir. Ben test ederim. Yine de çoğu durumda önemli bir fark yarattığını görmekten çok şaşıracaktım. –

+0

Yararlı yanıtlarınız için teşekkürler. Evet, test etmeliyim. Aslında bir röportaj için yaptığım bir programlama testinin bir parçası olarak ve varsayılan çözümün ne tür olacağını ya da en azından birisinin yanlış olmadığını bilmek istedim. – Bruce

7

Buffered * sınıflarının amacı, küçük yazma işlemlerini daha büyük bir şekilde birleştirmektir, böylece sistem çağrılarının sayısı azalır ve çıktı artırılır.

Bir BufferedWriter zaten bir arabellekte yazımlar topladığından, arabellek içindeki karakterleri başka bir arabelleğe dönüştürür ve bu arabayı temeldeki OutputStream'e tek bir işlemle yazar, OutputStream zaten büyük yazma işlemleriyle çalıştırılır. Bu nedenle, bir BufferedOutputStream birleştirilecek hiçbir şey bulamaz ve sadece gereksizdir.

Aynı şekilde, BufferedWriter için de geçerli olabilir: arabelleğe alma yalnızca yazar yalnızca bir seferde birkaç karakter geçerse yardımcı olacaktır. Arayanın yalnızca büyük dizeler yazdığını biliyorsanız, BufferedWriter'in birleştirilecek hiçbir şey bulamaz ve gereksizdir.

+1

Cevabınız için teşekkür ederiz. Bu çok açıklar. Sanırım arabelleğe almayı bırakmak kötü bir şeymiş gibi hissettim, ama söyledikleriniz çok mantıklı geliyor .. – Bruce

1

Evet, aşırı sıkışık. Javadoc for OutputStreamWriter'dan: "Her bir write() yönteminin çağrılması, kodlama dönüştürücüsünün belirtilen karakter (ler) üzerinde çağrılmasına neden olur. Sonuçtaki baytlar, temel çıktı akışına yazılmadan önce bir arabellekte biriktirilir.".

+0

@downvoter Burada Javadoc ile tartışıyorsunuz. Tam olarak hangi kısmı yanlış? – EJP

+0

(Ben downvoter değilim!) Bence bu mükemmel ve özlü bir cevap! Bir Tampon ile _wrapping_ tarafından, kodlayıcının sadece bir karakter kümelenmesi olduğunda tetiklendiğinden ve dahili bir arabelleği olduğundan, yalnızca bu arabellek dolduğunda temel yazımları tetikleyeceğinden emin oluruz. – SusanW

İlgili konular