CodeGym /Java-blogg /Tilfeldig /Input/output i Java. Klassene FileInputStream, FileOutput...
John Squirrels
Nivå
San Francisco

Input/output i Java. Klassene FileInputStream, FileOutputStream og BufferedInputStream

Publisert i gruppen
"Hei! I dagens leksjon vil vi fortsette samtalen vår om inn- og utdatastrømmer i Java ( Java I/O ). Dette er ikke den første leksjonen om dette emnet, og det vil absolutt ikke være den siste :) Input/output i Java.  FileInputStream-, FileOutputStream- og BufferedInputStream-klasser - 1Som det skjer, gir Java-språket mange måter å jobbe med I/O på. Det er ganske mange klasser som implementerer denne funksjonaliteten, så vi har delt dem inn i flere leksjoner — slik at du ikke blir forvirret fra starten av :) Tidligere leksjoner kom vi inn på BufferedReader, samt InputStreamabstrakte OutputStreamklasser og flere etterkommere. I dag skal vi vurdere 3 nye klasser: FileInputStream,  FileOutputStream, og  BufferedInputStream.

FileOutputStream-klassen

Hovedformålet med FileOutputStreamklassen er å skrive bytes til en fil. Ikke noe komplisert :) FileOutputStreamer en av implementeringene av den OutputStreamabstrakte klassen. I konstruktøren tar objekter av denne klassen enten banen til målfilen (hvor bytene skal skrives) eller et Fileobjekt. Vi vil undersøke eksempler på hver:

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(); 
   } 
}
Da vi opprettet Fileobjektet, ga vi den ønskede banen til konstruktøren. Vi trenger ikke lage den på forhånd: hvis den ikke eksisterer, vil programmet lage den. Du kan også klare deg uten å lage et ekstra objekt, bare passere en streng med banen:

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(); 
   } 
} 
Resultatet i begge tilfeller vil være det samme. Vi kan åpne filen vår og se følgende der:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Men det er en nyanse her. Prøv å kjøre koden fra eksemplet ovenfor flere ganger på rad. Se så i filen og svar på dette spørsmålet: hvor mange linjer har den? Bare én. Men du kjørte koden flere ganger. Det viser seg at dataene blir overskrevet hver gang - de gamle erstattes av de nye. Hva gjør vi hvis det ikke passer oss og vi må skrive sekvensielt til filen? Hva om vi vil skrive en hilsen til en fil tre ganger på rad? Det hele er veldig enkelt. Siden språket ikke kan vite hvilken oppførsel vi trenger i hvert enkelt tilfelle, FileOutputStreamkan konstruktøren ta en ekstra parameter -boolean append. Hvis verdien er sann, vil dataene bli skrevet til slutten av filen. Hvis det er usant (og som standard er det usann), vil alle gamle data bli slettet og erstattet av nye data. La oss sjekke dette ved å kjøre vår modifiserte kode tre ganger:

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(); 
   } 
} 
Filinnhold:

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!
Nå er det annerledes! Ikke glem denne funksjonen når du bruker I/O-klasser. Det var en gang da jeg brukte timer på oppgaver, maset hjernen i timevis, prøvde å forstå hvordan dataene mine forsvant fra filene :) Og selvfølgelig, akkurat som med andre I/O-klasser, ikke glem å bruke close()metoden å frigjøre ressurser.

FileInputStream-klassen

Den FileInputStreamhar det motsatte formålet - å lese bytes fra en fil. På samme måte som FileOutputStreamarver OutputStream, stammer denne klassen fra den InputStreamabstrakte klassen. Vi skriver noen få linjer med tekst i " test.txt "-filen vår:

"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 i Java.  FileInputStream-, FileOutputStream- og BufferedInputStream-klasser - 2Slik ser det ut å lese data fra en fil ved hjelp av 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); 

       } 
   } 
}
Vi leser én byte fra filen, konverterer de leste bytene til tegn og viser dem på konsollen. Og her er konsollutgangen:

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

BufferedInputStream-klassen

Jeg tror, ​​gitt kunnskapen fra tidligere leksjoner, kan du enkelt si hvorfor vi trenger klassen BufferedInputStreamog hvilke fordeler den har sammenlignet med FileInputStream:) Vi har allerede møtt bufrede strømmer, så prøv å gjette (eller husk) før du fortsetter å lese :) Bufret strømmer er hovedsakelig nødvendig for å optimalisere I/O. Å få tilgang til en datakilde, for eksempel å lese fra en fil, er en kostbar operasjon når det gjelder ytelse, og å få tilgang til en fil for å lese hver byte er bortkastet. Derfor BufferedInputStreamleser data ikke én byte om gangen, men i blokker, og lagrer dem midlertidig i en spesiell buffer. Dette lar oss optimere programmet ved å redusere antall ganger vi får tilgang til filen. La oss se hvordan dette ser ut:

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); 
       } 
   } 
} 
Her har vi laget et BufferedInputStreamobjekt. Konstruktøren tar en forekomst av InputStreamklassen eller noen av dens etterkommere, det FileInputStreamvil også gjøre. Som et ekstra argument tar den bufferstørrelsen i byte. Takket være dette argumentet vil dataene nå leses fra filen, ikke én byte om gangen, men 200 byte om gangen! Tenk deg hvor mye vi har redusert antall filtilganger. For å sammenligne ytelse kan du ta en stor tekstfil (flere megabyte med tekst) og sammenligne hvor lang tid det tar i millisekunder å lese og sende ut til konsollen ved å bruke FileInputStreamog BufferedInputStream. Her er koden som viser begge alternativene:

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())); 
   }
}
Når jeg leste en 1,5 MB fil på datamaskinen min, FileInputStreamfullførte arbeidet på ~3500 millisekunder, men BufferedInputStreamklarte det på ~1700 millisekunder. Som du kan se, optimaliserte den bufrede strømmen arbeidet, og kuttet det i to! :) Vi vil fortsette å studere I/O-klasser — ses snart!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION