CodeGym /Java blog /Tilfældig /Input/output i Java. Klasserne FileInputStream, FileOutpu...
John Squirrels
Niveau
San Francisco

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

Udgivet i gruppen
"Hej! I dagens lektion vil vi fortsætte vores samtale om input- og outputstrømme i Java ( Java I/O ). Dette er ikke den første lektion om dette emne, og det bliver bestemt ikke den sidste :) Input/output i Java.  Klasserne FileInputStream, FileOutputStream og BufferedInputStream - 1Da det sker, giver Java-sproget mange måder at arbejde med I/O på. Der er en del klasser, der implementerer denne funktionalitet, så vi har delt dem op i flere lektioner — så du ikke bliver forvirret fra starten :) Tidligere lektioner, vi kom ind på BufferedReader, samt de InputStreamabstrakte OutputStreamklasser og flere efterkommere. I dag vil vi overveje 3 nye klasser: FileInputStream,  FileOutputStream, og  BufferedInputStream.

FileOutputStream-klassen

Hovedformålet med FileOutputStreamklassen er at skrive bytes til en fil. Intet kompliceret :) FileOutputStreamer en af ​​implementeringerne af den OutputStreamabstrakte klasse. I konstruktøren tager objekter af denne klasse enten stien til målfilen (hvor bytes skal skrives) eller et Fileobjekt. Vi vil undersøge 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 oprettede Fileobjektet, sendte vi den ønskede sti til konstruktøren. Vi behøver ikke oprette det på forhånd: hvis det ikke findes, vil programmet oprette det. Du kan også klare dig uden at oprette et ekstra objekt, blot sende en streng med stien:

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 vil i begge tilfælde være det samme. Vi kan åbne vores fil og se følgende der:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Men der er en nuance her. Prøv at køre koden fra eksemplet ovenfor flere gange i træk. Så kig i filen og svar på dette spørgsmål: hvor mange linjer har den? Bare en. Men du kørte koden flere gange. Det viser sig, at dataene overskrives hver gang - de gamle erstattes af de nye. Hvad gør vi, hvis det ikke passer os, og vi skal skrive sekventielt til filen? Hvad hvis vi vil skrive vores hilsen til en fil tre gange i træk? Det hele er meget enkelt. Da sproget ikke kan vide, hvilken adfærd vi har brug for i hvert enkelt tilfælde, FileOutputStreamkan konstruktøren tage en ekstra parameter —boolean append. Hvis værdien er sand, vil dataene blive skrevet til slutningen af ​​filen. Hvis det er falsk (og som standard er det falsk), vil alle gamle data blive slettet og erstattet af nye data. Lad os tjekke dette ved at køre vores ændrede kode tre gange:

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

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!
Nu er det anderledes! Glem ikke denne funktion, når du bruger I/O-klasser. Der var engang, hvor jeg brugte timevis på opgaver, slyngede mine hjerner i timevis, prøvede at forstå, hvordan mine data forsvandt fra filer :) Og selvfølgelig, ligesom med andre I/O-klasser, glem ikke at bruge close()metoden at frigøre ressourcer.

FileInputStream-klassen

Den FileInputStreamhar det modsatte formål - at læse bytes fra en fil. Ligesom FileOutputStreamarver OutputStreamstammer denne klasse fra den InputStreamabstrakte klasse. Vi skriver et par linjer tekst i vores " test.txt " fil:

"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.  Klasserne FileInputStream, FileOutputStream og BufferedInputStream - 2Sådan ser det ud at læse data fra en fil ved hjælp af 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 læser en byte fra filen, konverterer de læste bytes til tegn og viser dem på konsollen. Og her er konsoludgangen:

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, ​​givet viden fra tidligere lektioner, at du nemt kan sige, hvorfor vi har brug for klassen, BufferedInputStreamog hvilke fordele den har i forhold til FileInputStream:) Vi har allerede stødt på buffer-streams, så prøv at gætte (eller husk), før du fortsætter med at læse :) Bufret streams er primært nødvendige for at optimere I/O. Adgang til en datakilde, såsom at læse fra en fil, er en dyr operation med hensyn til ydeevne, og det er spild at få adgang til en fil for at læse hver byte. Derfor BufferedInputStreamlæser data ikke én byte ad gangen, men i blokke og gemmer dem midlertidigt i en speciel buffer. Dette lader os optimere programmet ved at reducere antallet af gange, vi får adgang til filen. Lad os se, hvordan dette ser ud:

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 lavede vi et BufferedInputStreamobjekt. Dens konstruktør tager en forekomst af InputStreamklassen eller nogen af ​​dens efterkommere, det FileInputStreamvil også gøre det. Som et yderligere argument tager det bufferstørrelsen i bytes. Takket være dette argument vil dataene nu blive læst fra filen ikke én byte ad gangen, men 200 bytes ad gangen! Forestil dig, hvor meget vi har reduceret antallet af filadgange. For at sammenligne ydeevne kan du tage en stor tekstfil (adskillige megabyte tekst) og sammenligne, hvor lang tid det tager i millisekunder at læse og udlæse til konsollen ved hjælp af FileInputStreamog BufferedInputStream. Her er kode, der viser begge muligheder:

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 læste en 1,5 MB fil på min computer, FileInputStreamfuldførte arbejdet på ~3500 millisekunder, men BufferedInputStreamklarede det på ~1700 millisekunder. Som du kan se, optimerede den bufrede strøm arbejdet og halverede det! :) Vi vil fortsætte med at studere I/O-klasser — vi ses snart!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION