Tarayıcı ve BufferedReader


284

Bildiğim kadarıyla, Java'daki bir dosyadan karakter tabanlı veri okumak için en yaygın iki yöntem Scannerveya kullanıyor BufferedReader. Ayrıca BufferedReaderfiziksel disk işlemlerini önlemek için bir tampon kullanarak dosyaları verimli bir şekilde okuduğunu biliyorum .

Sorularım:

  • Scannerİyi performans sergiliyor mu BufferedReader?
  • Neden seçsin Scannerüzerinde BufferedReadertersi veya yardımcısı?

1
Genellikle Tarayıcı'yı standarttan okumak için de kullanıyorum ('Tarayıcı girişi = yeni Tarayıcı (System.in)' çok daha temiz geliyor). Aslında daha az verimli olup olmadığından emin değilim, ancak std'den okuma engellendiğinden, Tarayıcı'nın verimliliğinin sorun olacağını hayal edemiyorum.
dimo414

Yanıtlar:


201

ScannerBufferedReaderyalnızca akışı okurken jetonları akış içeriğinden ayrıştırmak için kullanılır ve özel ayrıştırma yapmaz.

Aslında bir geçebilir BufferedReadera scannerayrıştırmak için karakter kaynağı olarak.


55
BufferedReader senkronize edilir ve Tarayıcı değildir, bu yüzden karar vermek size kalmış.
Reuben

1
Bu konunun eski olduğunu biliyorum, ancak Process (sağlanan bir dış komutun çıktısını yakalama) tarafından sağlanan akışları içerik slurp çalışırken BufferedReader kullanarak işletim sistemleri arasında karışık sonuçlar oldu. Kodumu Tarayıcı'yı kullanacak şekilde değiştirdikten sonra, ayrı bir cevapta belirtildiği gibi , işler tutarlı ve beklendiği gibi davranmaya başladı.
2013

@ Reuben Ama Scannersonuçta girişi için senkronize edilmiş başka bir şeye bağlıdır.
Lorne Marquis

189

Şu anda en son JDK6 sürümü / derlemesinde (b27), ( 8192 karakterlerinin ) yerine Scannerdaha küçük bir arabellek ( 1024 karakter ) vardır, ancak bu fazlasıyla yeterlidir.BufferedReader

Seçim gelince, kullanmak Scanneristersen ayrıştırmak dosyayı kullanmak BufferedReaderisterseniz okumak dosyayı satır satır. Ayrıca, söz konusu API belgelerinin tanıtım metnine de bakın.

  • Ayrıştırma = verilen girdiyi belirteç (parça) olarak yorumlama. Belirli parçaları doğrudan int, string, ondalık, vb. Olarak geri verebilir . Sınıftaki tüm bu nextXxx()yöntemlere de bakın Scanner.
  • Okuma = aptal akış. Size tüm karakterleri geri vermeye devam eder ve sırayla yararlı bir şey eşleştirmek veya oluşturmak isteyip istemediğinizi manuel olarak incelemeniz gerekir. Ama yine de bunu yapmanız gerekmiyorsa, o zaman okumak yeterlidir.

1
Güzel bir. Tampon ucu için teşekkürler. Yerel okumalar son derece pahalı olduğu için boyunca arıyordu.
25'te ulaşın

7
@Asif: ayrıştırma = verilen girdiyi belirteçler (parçalar) olarak yorumlama. Belirli parçaları doğrudan int, string, ondalık, vb. Olarak geri verebilir. Scanner sınıfındaki tüm nextXxx () yöntemlerine de bakın. Okuma = aptal akış. Size tüm karakterleri geri vermeye devam eder ve sırayla yararlı bir şey eşleştirmek veya oluşturmak isteyip istemediğinizi manuel olarak incelemeniz gerekir. Ama yine de bunu yapmanız gerekmiyorsa, o zaman okumak yeterlidir.
BalusC

@BalusC Tamam Zaten kullandım, readInt();readFloat (); Şimdi ayrıştırma ne demek var. ve BalusC sohbet odasında sadece 10 dakika bana biraz zaman ayırabilir misin, arabelleğe alınmış, nasıl çalıştığı hakkında çok az şey sormak istiyorum.
Asif Mushtaq

BufferedReaderScanner'ın yapıcısına ne sarıyorum ? bu iyi bir fikir mi?
vivek

1
Scanner'nin arabelleği, desen eşleşmesi için gerektiği gibi genişletilecektir. Bu nedenle, daha büyük bir arabellek istiyorsanız, yalnızca çağırmanız gerekir, örneğin findWithinHorizon("\\z", 8192), ve daha sonra, 8192karakter kapasitesine sahip bir arabellek (veya bundan daha küçükse tüm dosya) kullanır.
Holger

77

Bunu gör bağlantıya , aşağıda alıntılanmıştır:

Bir BufferedReader, altlık akışından verimli bir şekilde okumak için tasarlanmış basit bir sınıftır. Genel olarak, bir FileReader gibi bir Reader'dan yapılan her okuma isteği, temel akışa karşılık gelen bir okuma talebinin yapılmasına neden olur. Read () veya readLine () öğelerinin her çağrılması, baytların dosyadan okunmasına, karakterlere dönüştürülmesine ve daha sonra döndürülmesine neden olabilir, bu da çok verimsiz olabilir. Bir Reader bir BufferedReader'da çarpıtıldığında verimlilik önemli ölçüde artırılır.

BufferedReader senkronize olduğundan, bir BufferedReader'daki okuma işlemleri birden çok iş parçacığından güvenle yapılabilir.

Öte yandan bir tarayıcıda çok daha fazla peynir bulunur; bir BufferedReader'ın yapabileceği her şeyi ve aynı verimlilik seviyesinde yapabilir. Bununla birlikte, bir tarayıcı, normal ifadeler kullanarak temel türler ve dizeler için temel akışı ayrıştırabilir. Ayrıca, altta yatan akışı seçtiğiniz sınırlayıcı ile de belirtebilir. Ayrıca, sınırlayıcıyı göz ardı ederek altta yatan akışın ileri taramasını da yapabilir!

Ancak tarayıcı iş parçacığı için güvenli değildir, harici olarak senkronize edilmesi gerekir.

BufferedReader veya Tarayıcı kullanma seçeneği, basit bir günlük okuyucu yazıyorsanız, buffered okuyucu yeterlidir, yazdığınız koda bağlıdır. Ancak bir XML ayrıştırıcı yazıyorsanız Tarayıcı daha doğal bir seçimdir.

Girişi okurken bile, kullanıcı girişini satır satır kabul etmek ve sadece bir dosyaya eklemek istiyorsanız, bir BufferedReader yeterince iyidir. Öte yandan, kullanıcı girişini birden fazla seçeneğe sahip bir komut olarak kabul etmek ve ardından belirtilen komuta ve seçeneklere göre farklı işlemler gerçekleştirmek istiyorsanız, Tarayıcı daha uygun olacaktır.


"Öte yandan bir tarayıcıda çok daha fazla peynir var; BufferedReader'ın yapabileceği her şeyi ve aynı verimlilik seviyesinde yapabilir." Kabul etmeyin, BufferedReader Tarayıcı ile karşılaştırıldığında biraz daha hızlıdır çünkü Tarayıcı giriş verilerini ayrıştırır ve BufferedReader sadece karakter dizisini okur.
Pratik

40
  1. BufferedReaderarabellek tarayıcıdan önemli ölçüde daha büyük. BufferedReaderBir akıştan uzun dizeler almak için kullanın ve bir akıştan Scannerbelirli türde bir jetonu ayrıştırmak istiyorsanız kullanın.

  2. Scannerözel sınırlayıcı kullanarak tokenize kullanabilir ve BufferedReaderyalnızca String'i okuyabilir ve depolayabilirken akışı ilkel veri türlerine ayrıştırabilir .

  3. BufferedReadersenkronize iken Scannerdeğil. BufferedReaderBirden çok iş parçacığıyla çalışıyorsanız kullanın .

  4. ScannerBufferedReaderanında atarken IOException'ı gizler .


18

BufferedReaderMetin okumak için kullanmanızı öneririm . Scannergizler IOExceptionise BufferedReaderhemen atar.


12

BufferedReader ve Tarayıcı arasındaki fark aşağıdaki gibidir:

  1. BufferedReader senkronize edildi ancak Tarayıcı senkronize değil .
  2. BufferedReader iş parçacığı için güvenli ancak Tarayıcı iş parçacığı için güvenli değil .
  3. BufferedReader daha büyük arabellek belleğine sahiptir ancak Tarayıcı daha küçük arabellek belleğine sahiptir .
  4. BufferedReader daha hızlıdır ancak Tarayıcı yürütme sırasında daha yavaştır .
  5. Konsoldan satır okuma kodu:

    Arabellek Okuyucu :

     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br= new BufferedReader(isr);
     String st= br.readLine();

    Tarayıcı :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();

8

BufferedReader ve Tarayıcı arasındaki farklar aşağıdadır

  1. BufferedReader yalnızca verileri okur ancak tarayıcı verileri de ayrıştırır.
  2. String'i yalnızca BufferedReader'ı kullanarak okuyabilirsiniz, ancak Tarayıcı'yı kullanarak int, long veya float'ı okuyabilirsiniz.
  3. BufferedReader Tarayıcı'dan daha eskidir, Tarayıcı JDK 5 sürümüne eklenirken jdk 1.1'den itibaren mevcuttur.
  4. BufferedReader'ın Arabellek boyutu, 1KB Tarayıcı ile karşılaştırıldığında büyüktür (8KB).
  5. BufferedReader uzun String içeren dosyaları okumak için daha uygundur, Tarayıcı ise komut isteminden küçük kullanıcı girişlerini okumak için daha uygundur.
  6. BufferedReader senkronize edilir, ancak Tarayıcı değildir, yani Tarayıcı'yı birden çok iş parçacığı arasında paylaşamazsınız.
  7. BufferedReader, ayrıştırmaya zaman harcamadığından Tarayıcı'dan daha hızlı
  8. BufferedReader Tarayıcı ile karşılaştırıldığında biraz daha hızlı
  9. BufferedReader, java.io paketinden ve Tarayıcı, seçimimizi seçebileceğimiz noktalara dayanarak java.util paketinden.

Teşekkürler


6

Temel Farklılıklar:

  1. Tarayıcı

  • İlkel türleri ve dizeleri düzenli ifadeler kullanarak ayrıştırabilen basit bir metin tarayıcı.
  • Bir Tarayıcı varsayılan olarak boşlukla eşleşen bir sınırlayıcı deseni kullanarak girişlerini belirteçlere böler. Elde edilen tokenler daha sonra çeşitli sonraki yöntemler kullanılarak farklı tiplerdeki değerlere dönüştürülebilir.

Misal

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

aşağıdaki çıktıyı yazdırır:

 1
 2
 red
 blue 

Dört jetonun tümünü aynı anda ayrıştırmak için normal bir ifade kullanan bu kodla aynı çıktı üretilebilir:

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i=1; i<=result.groupCount(); i++)
     System.out.println(result.group(i));
 s.close(); `


  1. BufferedReader:

    • Karakterlerin, dizilerin ve satırların verimli okunmasını sağlamak için karakterleri arabelleğe alan karakter giriş akışından metin okur.

    • Arabellek boyutu belirtilebilir veya varsayılan boyut kullanılabilir. Varsayılan, çoğu amaç için yeterince büyüktür.

Genel olarak, bir Reader'dan yapılan her bir okuma talebi, alttaki karakter veya bayt akışından karşılık gelen bir okuma talebinin yapılmasına neden olur. Bu nedenle, bir BufferedReader'ın fileReaders ve InputStreamReaders gibi read () işlemleri maliyetli olabilecek herhangi bir Reader'ın etrafına sarılması tavsiye edilir. Örneğin,

BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));

girdiyi belirtilen dosyadan arabelleğe alır. Arabelleğe alma olmadan, read () veya readLine () öğelerinin her çağrılması baytların dosyadan okunmasına, karakterlere dönüştürülmesine ve daha sonra döndürülmesine neden olabilir, bu da çok verimsiz olabilir. Metin girişi için DataInputStreams kullanan programlar, her DataInputStream öğesini uygun bir BufferedReader ile değiştirerek yerelleştirilebilir.

Kaynak: Link


3

Java gibi girdi almanın farklı yolları vardır:

1) BufferedReader 2) Tarayıcı 3) Komut Satırı Bağımsız Değişkenleri

BufferedReader Karakterlerin, dizilerin ve satırların verimli okunmasını sağlamak için karakterleri arabelleğe alan bir karakter giriş akışından metin okuyun.

Tarayıcı, ilkel türleri ve dizeleri normal ifadeler kullanarak ayrıştırabilen basit bir metin tarayıcıdır.

basit bir günlük okuyucu yazıyorsanız Tampon okuyucu yeterlidir. XML ayrıştırıcı yazıyorsanız Tarayıcı daha doğal bir seçimdir.

Daha fazla bilgi için lütfen bakınız:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69


1

Aşağıdaki cevap Konsoldan Okuma'dan alınmıştır : JAVA Scanner vs BufferedReader

Konsoldan bir girdi okunduğunda, bunu başarmak için iki seçenek vardır. İlk kullanan Scanner, başka kullanan BufferedReader. Her ikisinin de farklı özellikleri var. Nasıl kullanılacağı farklıdır.

Tarayıcı verilen girdi belirteci olarak kabul edildi. BufferedReader, girdi olarak verilen satırları dize olarak okur. Tarayıcı, nextInt (), nextFloat () gibi kendi kendine ayrıştırma özellikleri sağlar.

Peki, diğerleri arasındaki farklar nelerdir?

  • Tarayıcı verilen girdi belirteci olarak kabul edildi. Akış satırı / String olarak BufferedReader
  • Regex kullanarak verilen tarayıcı tarayıcı tokenleştirdi. BufferedReader kullanımı ekstra kod yazmalıdır
  • BufferedReader Tarayıcı * nokta no. 2
  • Tarayıcı senkronize değil, BufferedReader senkronize edildi

Tarayıcı, JDK 1.5 sürümünden beri geliyor.

Tarayıcı veya Tamponlu Okuyucu ne zaman kullanılmalıdır?

Biri tokenize, diğerleri akış çizgisi kullanarak ikisi arasındaki temel farklılıklara bakın. Ayrıştırma özelliklerine ihtiyacınız olduğunda bunun yerine Tarayıcı'yı kullanın. Ancak, BufferedReader ile daha rahatım. Bir Dosyadan okumanız gerektiğinde, BufferedReader kullanın, çünkü bir dosyayı okurken tampon kullanır. Veya Tarayıcı'ya giriş olarak BufferedReader'ı kullanabilirsiniz.


0
  1. BufferedReader muhtemelen size daha iyi performans verecektir (çünkü Tarayıcı InputStreamReader, görünüm kaynaklarına dayanmaktadır).ups, dosyalardan okumak için nio kullanır. Büyük dosyalar için nio performansını BufferedReader performansına karşı test ettiğimde nio biraz daha iyi performans gösteriyor.
  2. Dosyadan okumak için Apache Commons IO'yu deneyin.

0

Ben Scannerkontrol istisnalar atmaz ve bu nedenle kullanım daha akıcı bir kod sonuç çünkü tercih ederim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.