Soru BufferedReader'da işaretleme ve sıfırlama nedir?


Neler olduğunu bilmek isterim mark() ve reset() Yöntemleri BufferedReader? Onları nasıl kullanırım? Javadoc'u okudum ama yeni başlayan biri olarak anlayamadım.


21
2017-11-23 09:47


Menşei




Cevaplar:


mark ve reset akış yöntemleri, akışta geriye doğru atlamak ve verileri yeniden okumak için bir yol sağlar.

Aradığın zaman mark() üzerinde BufferedReader Bu noktadan okuduğunuz verileri dahili tamponunda iletmeye başlayacaktır. Aradığın zaman reset() Akışın işaretlenmiş konumuna geri dönecek, böylece bir sonraki read()s bellek içi tampon tarafından tatmin edilecektir. Bu tamponun sonunu okurken, o zaman taze bir veri okumaya geri döner. BufferedInputStream aynı şekilde çalışır.

İnt parametresi mark maksimum sayıda karaktere sahip olduğunu belirtir ( BufferedReader) veya bayt (için BufferedInputStream) geriye doğru gidebilmek için. İşaretli konumu çok fazla veri okuyorsanız, işaret "geçersiz kılınabilir" ve arama yapılabilir. reset() bir istisna ile başarısız olur.

Küçük bir örnek:

BufferedReader r = new BufferedReader(new StringReader(
    "Happy Birthday to You!\n" +
    "Happy Birthday, dear " + System.getProperty("user.name") + "!"));
r.mark(1000); // save the data we are about to read
System.out.println(r.readLine()); // read the first line
r.reset(); // jump back to the marked position
r.mark(1000); // start saving the data again
System.out.println(r.readLine()); // read the first line again
System.out.println(r.readLine()); // read the second line
r.reset(); // jump back to the marked position
System.out.println(r.readLine()); // read the first line one final time

Bu örnekte, StringReader içinde BufferedReader almak için readLine() yöntem, ama StringReaders zaten destek mark ve reset kendi başlarına! Birinden okunan akışlar bellekte veri kaynağı genellikle destek mark ve reset kendileri, çünkü zaten tüm verileri hafızaya aldılar, böylece tekrar okumaları kolaylaşır. Dosyalardan veya borulardan veya ağ soketlerinden okunan akışlar doğal olarak desteklenmez mark ve resetAncak, her zaman bu özelliği herhangi bir akışa BufferedInputStream veya BufferedReader.


13
2017-11-23 10:22



ve () 'deki parametresi nedir? - Asif Mushtaq
@UnKnown cevabı genişlettim - Boann


mark() bir akışta belirli bir noktayı işaretlemek ve reset() akışı en son işarete sıfırlar. Bu yöntemler bir book-marking Yaklaşan verileri incelemek için akışta ilerlemenizi sağlayan özellik.

Bundan belgeleri:

işaret() yöntem, akıştaki "sıfırlama" tarafından girişin yapılabileceği bir konumu işaretler.   reset () yönteminin çağrılması. ReadLimit parametresi,   önce işaretini ayarladıktan sonra akıştan okunabilen chars   işareti geçersiz olur. Örneğin, eğer okunırsa işaret () çağrılırsa   10 limiti, daha sonra 11 veri akışı akıştan okunduğunda   reset () yöntemi çağrılmadan önce işaret geçersiz ve   işareti hatırlamak için akış nesnesi örneği gerekli değildir. Bunu not et   Bu yöntemle hatırlanabilecek karakter sayısı   Dahili okuma arabelleğinin boyutundan daha büyük. Ayrıca değil   bağımlı akış destek işaretine / sıfırlamaya bağlı   işlevsellik.


8
2017-11-23 10:22



ayrıca sadece bunu baştan işaretlemek ve arabelleği yeniden okumak için baştan başa dönmek için kullanabilir misiniz? örneğin bir dosyayı iki kez okumak isterseniz. Bir kez içerik almak için, başa geri dönün, sonra tekrar okuyun? - anon58192932
ve bu parametre nedir? - Asif Mushtaq


Reader::mark(int readLimit) belgelere göre:

Bu okuyucuda bir işaret konumu belirler. Parametre readLimit gösterir   işaretinden önce kaç karakter okunabiliyor geçersiz.   Sıfırlama () çağrısı, okuyucuyu işaretli konuma geri yerleştirecektir.   readLimit aşılmamışsa.

Örnek:

import java.io.*;
import static java.lang.System.out;

public class App {

    public static final String TEST_STR = "Line 1\nLine 2\nLine 3\nLine 4\n";

    public static void main(String[] args) {

        try (BufferedReader in = new BufferedReader(new StringReader(TEST_STR))) {

            // first check if this Reader support mark operation
            if (in.markSupported()) {

                out.println(in.readLine());
                in.mark(0);                     // mark 'Line 2'
                out.println(in.readLine());
                out.println(in.readLine());
                in.reset();                     // reset 'Line 2'
                out.println(in.readLine());
                in.reset();                     // reset 'Line 2'
                out.println(in.readLine());
                in.mark(0);                     // mark 'Line 3'
                out.println(in.readLine());
                in.reset();                     // reset 'Line 3'
                out.println(in.readLine());
                out.println(in.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Çıktı:

Line 1
Line 2
Line 3
Line 2
Line 2
Line 3
Line 3
Line 4

6
2018-01-19 15:23



Nasıl arayabilirsin reset()? Eğer düşündüm ki mark() okunan bir 0 değeriyle, bir karakter okunduğunda işaretleyici geçersiz hale gelir ve sıfırlamayı çağırmak imkansızdır. Cevabınızı açıklayabilir misiniz? - snooze92
@ snooze92 Sadece bu örneği çalıştırmak ve değiştirmek için deneyin markLimit argüman mark yöntem. Her zaman aynı sonucu elde edeceksin. Ayrıca benzer örneklere bakın: 1, 2. Aslında birileri bana bunun hakkında bir açıklama yaptığını sormak istedim. - Anton Dozortsev
Kendi kendime daha fazla örnek yürüttükten sonra anlıyorum. mark(readAheadLimit)/reset() mekanizma biraz daha iyi. Temel olarak mark yöntem basitçe bir noktayı işaretler. mevcut arabellek, ve reset Bu işaretlenmiş noktaya geri dönelim. Şey, işaretlenmiş noktaya erişme olasılığını korumak için tampon boyutunu arttırması gerektiği için, bir dosya veya akıştaki bir noktayı işaretlemek anlamına gelmez. Bu yüzden bir meli Tampon büyüklüğünden nispeten küçük bir limit kullanın. - snooze92
İtibariyle "Örnek, neden 0 sınırı (veya aslında herhangi bir sınır) ile çalışıyor" açıklamak da oldukça kolaydır. Varsayılan arabellek boyutu (her iki örnekte de kullanılır) 4096'dır. Örnekler için kullanılan String o kadar küçüktür ki, BufferedReader oluşturulduğu anda ilk tamponda tamamen okunur. Daha sonra herhangi bir şey okumaz, bu nedenle limit parametresi hiç kullanılmaz ... bu da örneklemi oldukça anlamsız ve kafa karıştırıcı IMHO yapar. BufferedReader kurucularında çok küçük bir arabellek boyutu (ör. 2 veya 3) eklemek için örneklerin biraz değiştirilmesi, geçersiz işaret istisnaları atar. - snooze92
@ snooze92 Açıklama için teşekkürler. Yorumlarınız dile getirildi. - Anton Dozortsev


Okuyucu arayüzü değil dönmene izin ver, sadece okuyabilirsin. Öte yandan, BufferedReader bir arabellek yaratır, bu yüzden okurken biraz geri dönebilirsiniz. Ve bu yöntemlerin ne için olduğunu.

Mark () yöntemi ile bir konuma "işaretleyici" yerleştirirsiniz, sonra okuyabilirsiniz. İşaretlediğiniz pozisyonu geri getirmek istediğinizi anladığınızda, bunun için reset () işlevini kullanın. Ve bu noktadan yine aynı değerleri okuyorsunuz. İstediğiniz her şey için kullanabilirsiniz.


1
2017-11-23 09:58





BufferReader = "123456789" 'da aşağıdaki karakterlere sahip olduğunuzu düşünün, eğer' 5 'karakterine göre pozisyon 4'ü işaretlerseniz ve BufferReader'ınızı sıfırlarsanız, 12345 ile sonuçlanırsınız.


1
2017-11-23 10:12



Bu cevapların yarısı ve ne sıfırlanıyor? - eeerahul
Hey uygun bir cevap verdi. Sıfırla, okunacak karaktere işaret eden işaretçiyi işaretlendiği konuma getirir. - Umang Desai


İşte bir örnek.

int bufferSize = 4;
int readLimit = 4
ByteArrayInputStream byteInputStream = new ByteArrayInputStream("123456789abcdef".getBytes());
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(byteInputStream, bufferSize)) {
        bufferedInputStream.mark(readLimit);
        System.out.print((char) bufferedInputStream.read());//byte1
        System.out.print((char) bufferedInputStream.read());//byte2
        System.out.print((char) bufferedInputStream.read());//byte3
        System.out.print((char) bufferedInputStream.read());//byte4
        bufferedInputStream.reset();
        System.out.print((char) bufferedInputStream.read());//byte5
        // Using this next reset() instead of the first one will throw an exception
        // bufferedInputStream.reset();

        System.out.print((char) bufferedInputStream.read());
        System.out.print((char) bufferedInputStream.read());
        System.out.print((char) bufferedInputStream.read());
    }

Çıktı: 12341234

Amacıyla readLimit, burada güzel bir referans.


0
2017-08-04 05:28