I programmi molto spesso includono un requisito per scrivere rapidamente i dati su un file o altrove. E questo solleva domande: come dovremmo farlo? Quale classe dovremmo scegliere? Oggi conosceremo un candidato adatto a questo ruolo: la classe BufferedWriter .

Perché abbiamo bisogno di BufferedWriter?

BufferedWriter è una classe che scrive caratteri bufferizzati in un flusso. Ti consente di ridurre il numero di volte in cui accedi ai supporti fisici. Cioè, invece di scrivere un singolo carattere ogni volta, scrive i dati in un buffer, quindi scrive tutti i caratteri sul supporto contemporaneamente.

Ciò aumenta notevolmente la velocità di scrittura. La dimensione predefinita del buffer è di 8192 caratteri, ma può essere modificata specificando una nuova dimensione nel costruttore:

BufferedWriter(Writer in, int sz)

Qui, il primo argomento del costruttore è un flusso che riceverà i dati che scriviamo. E si scopre che sz è la dimensione del nuovo buffer.

Java ha anche una classe BufferedReader : viene utilizzata per la lettura bufferizzata dei dati.

Cos'è esattamente un tampone? Facciamo un esempio di vita reale. Un tampone è come un cestino o un carrello della spesa al supermercato. Invece di andare alla cassa con un solo articolo, pagarlo, metterlo nel bagagliaio della tua auto e poi tornare indietro per un altro articolo, possiamo prendere un carrello della spesa, metterci dentro tutto ciò che vogliamo e poi pagare al checkout. Questo è esattamente il modo in cui funziona un buffer: raccoglie dati e poi prende tutto e lo scrive, invece di scrivere ogni frammento separatamente.

Costruttori e metodi della classe BufferedWriter

Ora diamo un'occhiata più da vicino alla classe BufferedWriter . Esistono due costruttori per la creazione di un oggetto:

public BufferedWriter(Writer out)
public BufferedWriter(Writer out, int sz)

Where out in entrambi i costruttori è il flusso su cui scrivere e sz , come già accennato, è la dimensione del buffer.

Anche la classe BufferedWriter ha diversi metodi. Oggi ne esamineremo alcuni più da vicino:

write(char[] matrice) Scrive una matrice di caratteri nel buffer
write(String s, int off, int len) Scrive parte di una stringa nel buffer
aggiungi (carattere c) Scrive un carattere nel buffer
append(SequenzaCaratteri csq, int inizio, int fine) Scrive parte di un array nel buffer
nuova linea() Scrive un separatore di riga
sciacquone() Svuota il flusso

Scriviamo un programma che scriverà un valore in un file. Per ilscrittoreparametro, passeremo aFileWriteral costruttore. Viene utilizzato per scrivere file di testo e ha diversi costruttori per inizializzare gli oggetti:

FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(FileDescriptor fd)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)

Per il nostro esempio, utilizzeremo un costruttore che accetta un nome file:

try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))){

	String message = "Hello, Amigo! This is a very important message!";
	bufferedWriter.write(message);
	bufferedWritter.flush();
}
catch(IOException ex){
System.out.println(ex.getMessage());
 }

Il nostro codice utilizzerà il metodo write(String str) per scrivere str nel file file.txt .

Ci sono altri metodi per scrivere:

  • write(char[] array ) — questa variante accetta e scrive un array di caratteri ;

  • write(String s, int off, int len) — questa variante accetta una stringa s ; un offset off , che è l'indice del carattere da cui iniziare a scrivere; e len , che è la lunghezza della stringa (sottostringa) da scrivere.

try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))){
	String message = "Hello, Amigo! This is a very important message!";
	bufferedWriter.write(message, 0, 11);
 	bufferedWriter.flush();

} catch(IOException ex) {
System.out.println(ex.getMessage());
}

Questo codice scriverà "Hello, Amig" nel file, poiché abbiamo detto al metodo di scrivere 11 caratteri a partire dall'indice 0.

Il nostro codice ha anche un blocco try-with resources :

try(BufferedWriter bufferedWritter = new BufferedWriter(new FileWriter("file.txt")))

Ciò significa che il metodo close() viene chiamato automaticamente su mybuffered Writeroggetto, perché implementa l' interfaccia AutoCloseable .

Il metodo flush() nel codice viene utilizzato per svuotare il flusso di output, forzando la scrittura di tutti i byte bufferizzati. La scrittura potrebbe non avvenire senza questa chiamata, poiché è ciò che indica che il buffer deve essere svuotato e che i byte bufferizzati devono essere scritti.

La classe BufferedWriter ha anche un metodo newLine() che aggiunge una nuova riga al nostro messaggio:

try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))) {
        String message = "Hello, Amigo! This is a very important message!";
        bufferedWriter.write(message, 0, 13);
        bufferedWriter.newLine();
        bufferedWriter.write(message, 15, 33);
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }

Nel file otteniamo:

Ciao, Amico!
Questo è un messaggio molto importante!

La firma del metodo append() è simile a questa:

public Writer append(CharSequence csq, int start, int end)

Viene utilizzato per aggiungere csq . Qui start è l'indice del primo carattere e end è l'indice dell'ultimo carattere della stringa (o sottostringa) da inserire. Il carattere con fine indice non viene inserito.

try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))) {
    String message = "Hello, Amigo! This is a very important message!";
    bufferedWriter.append(message, 0, 7);
    bufferedWriter.flush();
} catch (IOException ex) {
    System.out.println(ex.getMessage());
}

Questo codice ti darà:

Ciao,

Cioè, con il metodo append , specifichi quale parte della stringa aggiungere al buffer.

Osservando più da vicino la differenza tra write() e append() , vediamo innanzitutto che entrambi fanno la stessa cosa in linea di principio: scrivono valori.

Tuttavia, la differenza è che il metodo append è più recente e accetta un CharSequence come argomento e poiché String implementa CharSequence , possiamo passare Strings e StringBuilders e StringBuffers al metodo append . Ma il metodo write() accetterà solo un String .

Questo è tutto per ora! Oggi abbiamo familiarizzato con i buffer, come eseguire la scrittura bufferizzata su un file, nonché i metodi che puoi utilizzare per farlo.