CodeGym /Java Blogu /Rastgele /Java'da giriş/çıkış. FileInputStream, FileOutputStream ve...
John Squirrels
Seviye
San Francisco

Java'da giriş/çıkış. FileInputStream, FileOutputStream ve BufferedInputStream sınıfları

grupta yayınlandı
"Merhaba! Bugünkü dersimizde Java'daki girdi ve çıktı akışları ( Java I/O ) hakkındaki konuşmamıza devam edeceğiz. Bu konuyla ilgili ilk ders değil ve kesinlikle son da olmayacak :) Java'da giriş/çıkış.  FileInputStream, FileOutputStream ve BufferedInputStream sınıfları - 1Olduğu gibi Java dili, G/Ç ile çalışmak için pek çok yol sağlar. Bu işlevi uygulayan epeyce sınıf vardır, bu yüzden bunları birkaç derse ayırdık - böylece baştan kafanız karışmaz :) Geçmişte derslerin BufferedReaderyanı sıra InputStreamsoyut sınıflara ve birkaç alt sınıfa değindik.Bugün OutputStream3 yeni sınıfı ele alacağız: FileInputStream,  FileOutputStream, ve  BufferedInputStream.

FileOutputStream sınıfı

Sınıfın temel amacı, FileOutputStreambir dosyaya bayt yazmaktır. Hiçbir şey karmaşık değil :), soyut FileOutputStreamsınıfın uygulamalarından biridir OutputStream. Kurucuda, bu sınıfın nesneleri ya hedef dosyanın yolunu (baytların yazılması gereken yer) ya da bir Filenesneyi alır. Her birinin örneklerini inceleyeceğiz:

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(); 
   } 
}
Nesneyi oluştururken File, yapıcıya istenen yolu geçtik. Önceden oluşturmamıza gerek yok: eğer mevcut değilse, program onu ​​yaratacaktır. Ayrıca, fazladan bir nesne oluşturmadan, yalnızca yolla bir dize geçirerek de yapabilirsiniz:

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(); 
   } 
} 
Her iki durumda da sonuç aynı olacaktır. Dosyamızı açabilir ve orada aşağıdakileri görebiliriz:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Ama burada bir nüans var. Yukarıdaki örnekteki kodu art arda birkaç kez çalıştırmayı deneyin. Sonra dosyaya bakın ve şu soruyu cevaplayın: kaç satırı var? Sadece bir tane. Ancak kodu birkaç kez çalıştırdınız. Her seferinde verilerin üzerine yazıldığı ortaya çıktı - eskinin yerini yenisi alıyor. Bu bize uymuyorsa ve dosyaya sırayla yazmamız gerekiyorsa ne yapacağız? Bir dosyaya arka arkaya üç kez selamlamamızı yazmak istersek ne olur? Her şey çok basit. Dil, her durumda hangi davranışa ihtiyacımız olduğunu bilemediğinden, FileOutputStreamyapıcı ek bir parametre alabilir -boolean append. Değeri true ise, veriler dosyanın sonuna yazılacaktır. Yanlış ise (ve varsayılan olarak yanlıştır), tüm eski veriler silinecek ve yeni verilerle değiştirilecektir. Değiştirilen kodumuzu üç kez çalıştırarak bunu kontrol edelim:

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(); 
   } 
} 
Dosya içeriği:

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!
Şimdi bu farklı! G/Ç sınıflarını kullanırken bu özelliği unutmayın. close()Görevler üzerinde saatler harcadığım, saatlerce beynimi zorladığım, verilerimin dosyalardan nasıl kaybolduğunu anlamaya çalıştığım bir zaman vardı :) Ve tabii diğer I/O sınıflarında olduğu gibi, yöntemi kullanmayı unutmayın ücretsiz kaynaklara.

FileInputStream sınıfı

Bunun FileInputStreamtersi bir amacı vardır — bir dosyadan bayt okumak. Tıpkı FileOutputStreaminherits gibi OutputStream, bu sınıf da soyut sınıftan türemiştir InputStream. " test.txt " dosyamıza birkaç satırlık bir metin yazacağız :

"So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters"
Java'da giriş/çıkış.  FileInputStream, FileOutputStream ve BufferedInputStream sınıfları - 2Aşağıdakileri kullanarak bir dosyadan veri okumak nasıl görünür 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); 

       } 
   } 
}
Dosyadan bir byte okuyoruz, okunan byteları karaktere çeviriyoruz ve konsolda görüntülüyoruz. Ve işte konsol çıktısı:

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

BufferedInputStream sınıfı

BufferedInputStreamGeçmiş derslerdeki bilgileri göz önünde bulundurarak, sınıfa neden ihtiyaç duyduğumuzu ve kıyasla ne gibi avantajları olduğunu kolayca söyleyebilirsiniz FileInputStream:) Zaten arabelleğe alınmış akışlarla karşılaştık, bu yüzden okumaya devam etmeden önce tahmin etmeye (veya hatırlamaya) çalışın :) Arabelleğe alınmış akışlar, esas olarak G/Ç'yi optimize etmek için gereklidir. Bir dosyadan okumak gibi bir veri kaynağına erişmek, performans açısından pahalı bir işlemdir ve her baytı okumak için bir dosyaya erişmek israftır. Bu nedenle, BufferedInputStreamverileri her seferinde bir bayt olarak değil, bloklar halinde okur ve bunları geçici olarak özel bir arabellekte saklar. Bu, dosyaya erişme sayımızı azaltarak programı optimize etmemizi sağlar. Bunun neye benzediğini görelim:

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); 
       } 
   } 
} 
Burada bir nesne oluşturduk BufferedInputStream. Yapıcısı, sınıfın bir örneğini InputStreamveya soyundan herhangi birini alır, öyle FileInputStreamyapacaktır. Ek bir bağımsız değişken olarak arabellek boyutunu bayt cinsinden alır. Bu argüman sayesinde, veriler artık dosyadan bir seferde bir bayt değil, bir seferde 200 bayt okunacak! Dosya erişimi sayısını ne kadar azalttığımızı bir düşünün. Performansı karşılaştırmak için, büyük bir metin dosyası (birkaç megabaytlık metin) alabilir ve okumanın ve konsola çıkışın milisaniye cinsinden ne kadar sürdüğünü FileInputStreamve kullanarak karşılaştırabilirsiniz BufferedInputStream. İşte her iki seçeneği de gösteren kod:

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())); 
   }
}
Bilgisayarımda 1.5 MB'lık bir dosyayı okurken FileInputStreamişi ~3500 milisaniyede tamamladım ama BufferedInputStream~1700 milisaniyede başardım. Gördüğünüz gibi, arabelleğe alınmış akış işi optimize ederek yarıya indirdi! :) G/Ç sınıflarını incelemeye devam edeceğiz — yakında görüşürüz!
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION