JavaRush /Java Blog /Random-IT /I/O in Java. Classi FileInputStream, FileOutputStream, Bu...

I/O in Java. Classi FileInputStream, FileOutputStream, BufferedInputStream

Pubblicato nel gruppo Random-IT
Ciao! Nella lezione di oggi continueremo la conversazione sui flussi di input e output in Java, o Java I/O (“input-output”) in breve. Questa non è la prima conferenza su questo argomento, e non sarà l'ultima :) Si dà il caso che Java come linguaggio offra molte opportunità per lavorare con input/output. Ci sono molte classi che implementano questa funzionalità, quindi le abbiamo divise in più lezioni in modo da non confondervi all'inizio :) I/O in Java.  Classi FileInputStream, FileOutputStream, BufferedInputStream - 1Nelle lezioni precedenti abbiamo parlato di BufferedReader , così come delle classi astratte InputStream & OutputStream e diverse discendenti. Oggi esamineremo 3 nuove classi: FileInputStream , FileOutputStream e BufferedInputStream .

Classe FileOutputStream

Lo scopo principale della classe FileOutputStream è scrivere byte in un file. Niente di complicato :) FileOutputStream è una delle implementazioni della classe astratta OutputStream . Nel costruttore, gli oggetti di questa classe prendono il percorso del file di destinazione (in cui devono essere scritti i byte) o un oggetto della classe File. Consideriamo entrambi gli esempi:

public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Durante la creazione di un oggetto, Fileabbiamo specificato nel costruttore il percorso in cui dovrebbe trovarsi. Non è necessario crearlo in anticipo: se non esiste, sarà il programma a crearlo da solo. Puoi fare a meno di creare un oggetto aggiuntivo e passare semplicemente una stringa con l'indirizzo:

public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Il risultato in entrambi i casi sarà lo stesso. Possiamo aprire il nostro file e vedere lì:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
Tuttavia, c'è un avvertimento qui. Prova a eseguire il codice dell'esempio sopra più volte di seguito, quindi guarda il file e rispondi alla domanda: quante righe vedi scritte al suo interno? Solo uno. Ma hai eseguito il codice più volte. Tuttavia, si scopre che i dati venivano sovrascritti ogni volta, sostituendo quelli vecchi. Cosa succede se non siamo soddisfatti e abbiamo bisogno di una registrazione sequenziale? E se volessimo scrivere il nostro saluto su un file tre volte di seguito? Tutto è semplice qui. Poiché il linguaggio stesso non può sapere di quale tipo di comportamento abbiamo bisogno in ogni caso, FileOutputStreampuoi passare un parametro aggiuntivo al costruttore - boolean append. Se il suo valore è true , i dati verranno scritti alla fine del file. Se false (e il valore predefinito è false ), i vecchi dati verranno cancellati e verranno scritti nuovi dati. Testiamo ed eseguiamo il nostro codice modificato tre volte:

public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Risultato nel file:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Un'altra cosa! Tieni presente questa funzionalità quando usi le classi I/O. Un tempo, dovevo sedermi per ore sulle attività per capire dove andavano a finire i miei vecchi dati dai file :) E ovviamente, come nel caso di altre classi I/O, non dimenticare di rilasciare risorse tramite il file close().

Classe FileInputStream

La classe ha FileInputStreamlo scopo opposto: leggere byte da un file. Proprio come FileOutputStreaminherits OutputStream, questa classe deriva dalla classe astratta InputStream. Scriviamo diverse righe di testo nel nostro testo " test.txt ":

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
I/O in Java.  Classi FileInputStream, FileOutputStream, BufferedInputStream - 2 Questo è ciò che implementa l'implementazione della lettura dei dati da un file utilizzando FileInputStream:

public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Leggiamo un byte dal file, convertiamo i byte letti in caratteri e li trasmettiamo alla console. Ed ecco il risultato nella console:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

Classe BufferedInputStream

Penso che, data la conoscenza delle lezioni precedenti, puoi facilmente capire perché il corso è necessario BufferedInputStreame quali vantaggi ha rispetto FileInputStream:) Abbiamo già incontrato flussi bufferizzati, quindi prova a indovinare (o ricordare) prima di continuare a leggere :) Stream bufferizzati sono necessari principalmente per ottimizzare l'I/O. L'accesso a un'origine dati, ad esempio la lettura da un file, è un'operazione ad alto utilizzo di prestazioni. E accedere al file per leggere un byte ogni volta è uno spreco. Pertanto, BufferedInputStreamlegge i dati non un byte alla volta, ma in blocchi e li memorizza temporaneamente in un buffer speciale. Questo ci permette di ottimizzare il funzionamento del programma riducendo il numero di accessi al file. Vediamo come appare:

public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Qui abbiamo creato un oggetto BufferedInputStream. Accetta un oggetto o uno qualsiasi dei suoi successori come input , quindi andrà bene anche InputStreamquello precedente . FileInputStreamPrende la dimensione del buffer in byte come parametro aggiuntivo. Ora, grazie a questo, i dati verranno letti dal file non un byte alla volta, ma 200 alla volta! Immagina quanto abbiamo ridotto il numero di accessi ai file. Per confrontare le prestazioni, puoi prendere un file di testo di grandi dimensioni di diversi megabyte e confrontare il tempo impiegato per leggerlo e inviarlo alla console in millisecondi utilizzando FileInputStreame BufferedInputStream. Ecco entrambi gli esempi di codice:

public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");

      
       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
Durante la lettura di un file da 1,5 MB sul mio computer, FileInputStreamha svolto il lavoro in ~ 3500 millisecondi, ma qui BufferedInputStreamha svolto il lavoro in ~ 1700 millisecondi. Come puoi vedere, lo streaming bufferizzato ha ottimizzato le prestazioni del programma di 2 volte! :) Continueremo a studiare lezioni di I/O: a presto!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION