CodeGym /Java Blog /Random-IT /Input/output in Java. Classi FileInputStream, FileOutputS...
John Squirrels
Livello 41
San Francisco

Input/output in Java. Classi FileInputStream, FileOutputStream e BufferedInputStream

Pubblicato nel gruppo Random-IT
"Ciao! Nella lezione di oggi, continueremo la nostra conversazione sui flussi di input e output in Java ( Java I/O ). Questa non è la prima lezione su questo argomento, e certamente non sarà l'ultima :) Input/output in Java.  Classi FileInputStream, FileOutputStream e BufferedInputStream - 1Poiché accade, il linguaggio Java offre molti modi per lavorare con l'I / O. Ci sono alcune classi che implementano questa funzionalità, quindi le abbiamo divise in diverse lezioni, quindi non ti confonderai dall'inizio :) In passato lezioni, abbiamo toccato BufferedReader, così come le InputStreame OutputStreamclassi astratte e diversi discendenti.Oggi considereremo 3 nuove classi: FileInputStream,  FileOutputStream, e  BufferedInputStream.

La classe FileOutputStream

Lo scopo principale della FileOutputStreamclasse è scrivere byte in un file. Niente di complicato :) FileOutputStreamè una delle implementazioni della OutputStreamclasse astratta. Nel costruttore, gli oggetti di questa classe prendono il percorso del file di destinazione (dove dovrebbero essere scritti i byte) o un Fileoggetto. Esamineremo esempi di ciascuno:

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 CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
}
Durante la creazione dell'oggetto File, abbiamo passato il percorso desiderato al costruttore. Non abbiamo bisogno di crearlo in anticipo: se non esiste, il programma lo creerà. Puoi anche cavartela senza creare un oggetto extra, semplicemente passando una stringa con il percorso:

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 CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Il risultato in entrambi i casi sarà lo stesso. Possiamo aprire il nostro file e vedere quanto segue:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Ma c'è una sfumatura qui. Prova a eseguire il codice dell'esempio precedente più volte di seguito. Quindi guarda nel file e rispondi a questa domanda: quante righe ha? Solo uno. Ma hai eseguito il codice diverse volte. Si scopre che i dati vengono sovrascritti ogni volta: il vecchio viene sostituito dal nuovo. Cosa facciamo se non ci va bene e dobbiamo scrivere in sequenza sul file? E se volessimo scrivere il nostro saluto su un file tre volte di seguito? È tutto molto semplice. Dal momento che la lingua non può sapere di quale comportamento abbiamo bisogno in ogni caso, il FileOutputStreamcontrucutor può prendere un parametro aggiuntivo —boolean append. Se il suo valore è true, i dati verranno scritti alla fine del file. Se è falso (e per impostazione predefinita è falso), tutti i vecchi dati verranno cancellati e sostituiti da nuovi dati. Controlliamo questo eseguendo 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 CodeGym — The best site for would-be programmers!\r\n"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Contenuto dell'archivio:

Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers!
Ora è diverso! Non dimenticare questa funzione quando usi le classi I/O. C'è stato un tempo in cui passavo ore in attività, a scervellarmi per ore, cercando di capire come i miei dati stavano scomparendo dai file :) E ovviamente, proprio come con altre classi di I/O, non dimenticare di usare il close()metodo per liberare risorse.

La classe FileInputStream

ha FileInputStreamlo scopo opposto: leggere byte da un file. Proprio come FileOutputStreaminherits OutputStream, questa classe deriva dalla InputStreamclasse astratta. Scriveremo alcune righe di testo nel nostro file " 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"
Input/output in Java.  Classi FileInputStream, FileOutputStream e BufferedInputStream - 2Ecco come appare leggere i dati da un file usando 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 visualizziamo sulla console. Ed ecco l'output della console:

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

La classe BufferedInputStream

Penso che, data la conoscenza delle lezioni precedenti, puoi facilmente dire perché abbiamo bisogno della BufferedInputStreamclasse e quali vantaggi ha rispetto a FileInputStream:) Abbiamo già incontrato flussi bufferizzati, quindi prova a indovinare (o ricordare) prima di continuare a leggere :) I flussi bufferizzati sono necessari principalmente per ottimizzare l'I/O. L'accesso a un'origine dati, come la lettura da un file, è un'operazione costosa in termini di prestazioni e accedere a un file per leggere ogni byte è uno spreco. Ecco perché BufferedInputStreamlegge i dati non un byte alla volta, ma in blocchi, e li memorizza temporaneamente in un buffer speciale. Questo ci consente di ottimizzare il programma riducendo il numero di volte in cui accediamo 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 BufferedInputStreamoggetto. Il suo costruttore accetta un'istanza della InputStreamclasse o uno qualsiasi dei suoi discendenti, quindi FileInputStreamlo farà. Come argomento aggiuntivo, accetta la dimensione del buffer in byte. Grazie a questo argomento, i dati verranno ora letti dal file non un byte alla volta, ma 200 byte 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 (diversi megabyte di testo) e confrontare il tempo impiegato in millisecondi per la lettura e l'output nella console utilizzando FileInputStreame BufferedInputStream. Ecco il codice che dimostra entrambe le opzioni:

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, FileInputStreamho completato il lavoro in ~ 3500 millisecondi, ma BufferedInputStreaml'ho gestito in ~ 1700 millisecondi. Come puoi vedere, il flusso bufferizzato ha ottimizzato il lavoro, tagliandolo a metà! :) Continueremo a studiare i corsi di I/O — a presto!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION