JavaRush /จาวาบล็อก /Random-TH /I/O ในภาษาจาวา คลาส FileInputStream, FileOutputStream, Bu...

I/O ในภาษาจาวา คลาส FileInputStream, FileOutputStream, BufferedInputStream

เผยแพร่ในกลุ่ม
สวัสดี! ในการบรรยายวันนี้ เราจะพูดคุยกันต่อเกี่ยวกับสตรีมอินพุตและเอาท์พุตใน Java หรือ เรียกสั้น ๆ ว่า Java I/O (“อินพุต-เอาต์พุต”) นี่ไม่ใช่การบรรยายครั้งแรกในหัวข้อนี้ และจะไม่ใช่ครั้งสุดท้าย :) มันบังเอิญว่า Java ในฐานะภาษาหนึ่งให้โอกาสมากมายในการทำงานกับอินพุต/เอาท์พุต มีคลาสค่อนข้างมากที่ใช้ฟังก์ชันนี้ ดังนั้นเราจึงแบ่งคลาสออกเป็นหลายคลาสเพื่อที่คุณจะได้ไม่สับสนในตอนแรก :) I/O ในภาษาจาวา  คลาส FileInputStream, FileOutputStream, BufferedInputStream - 1ในการบรรยายครั้งก่อนๆ เราได้พูดถึงBufferedReaderเช่นเดียวกับคลาสนามธรรมInputStream & OutputStreamและอีกหลายคลาส ลูกหลาน วันนี้เราจะดูคลาสใหม่ 3 คลาส: FileInputStream , FileOutputStreamและBufferedInputStream

คลาส FileOutputStream

วัตถุประสงค์หลักของ คลาส FileOutputStreamคือการเขียนไบต์ไปยังไฟล์ ไม่มีอะไรซับซ้อน :) FileOutputStreamเป็นหนึ่งในการใช้งานของคลาสOutputStreamนามธรรม ใน Constructor อ็อบเจ็กต์ของคลาสนี้จะใช้พาธไปยังไฟล์เป้าหมาย (ซึ่งจำเป็นต้องเขียนไบต์) หรืออ็อบเจ็กต์ของFileคลาส ลองดูทั้งสองตัวอย่าง:
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();
   }
}
เมื่อสร้างวัตถุFileเราได้ระบุไว้ใน Constructor ว่าควรอยู่ที่ใด ไม่จำเป็นต้องสร้างไว้ล่วงหน้า หากไม่มี โปรแกรมจะสร้างเอง คุณสามารถทำได้โดยไม่ต้องสร้างวัตถุเพิ่มเติมและเพียงแค่ส่งสตริงที่มีที่อยู่:
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();
   }
}
ผลลัพธ์ในทั้งสองกรณีจะเหมือนกัน เราสามารถเปิดไฟล์ของเราและดูที่นั่น:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
อย่างไรก็ตามมีข้อแม้ประการหนึ่งที่นี่ ลองรันโค้ดจากตัวอย่างด้านบนหลายๆ ครั้งติดต่อกัน จากนั้นดูไฟล์และตอบคำถาม: คุณเห็นข้อความเขียนอยู่ในนั้นกี่บรรทัด? แค่หนึ่ง. แต่คุณรันโค้ดหลายครั้ง อย่างไรก็ตามปรากฎว่าข้อมูลถูกเขียนทับในแต่ละครั้งโดยแทนที่ข้อมูลเก่า จะเป็นอย่างไรถ้าเราไม่พอใจกับสิ่งนี้และต้องการการบันทึกตามลำดับ? จะเป็นอย่างไรหากเราต้องการเขียนคำทักทายของเราลงในไฟล์สามครั้งติดต่อกัน? ทุกอย่างเรียบง่ายที่นี่ เนื่องจากตัวภาษาเองไม่สามารถรู้ได้ว่าเราต้องการพฤติกรรมประเภทใดในแต่ละกรณีFileOutputStreamคุณจึงสามารถส่งพารามิเตอร์เพิ่มเติมไปยังตัวสร้างได้boolean append- หากค่าเป็นtrueข้อมูลจะถูกเขียนที่ส่วนท้ายของไฟล์ หากเป็นเท็จ (และค่าเริ่มต้นคือfalse ) ข้อมูลเก่าจะถูกลบและข้อมูลใหม่จะถูกเขียน มาทดสอบและรันโค้ดที่แก้ไขของเราสามครั้ง:
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();
   }
}
ผลลัพธ์ในไฟล์:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
อีกสิ่งหนึ่งที่! คำนึงถึงคุณลักษณะนี้เมื่อใช้คลาส I/O ครั้งหนึ่ง ฉันต้องนั่งทำงานเป็นเวลาหลายชั่วโมงเพื่อทำความเข้าใจว่าข้อมูลเก่าของฉันไปจากไฟล์ไหน :) และแน่นอนว่า เช่นเดียวกับในกรณีของคลาส I/O อื่นๆ อย่าลืมเกี่ยวกับการปล่อยทรัพยากรผ่านclose().

คลาส FileInputStream

คลาสมีFileInputStreamวัตถุประสงค์ตรงกันข้าม - การอ่านไบต์จากไฟล์ เช่นเดียวกับการFileOutputStreamสืบทอดOutputStreamคลาสนี้มาจากคลาสนามธรรม มาเขียน ข้อความหลายบรรทัด InputStreamลงในข้อความของเรา “ 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 ในภาษาจาวา  คลาส FileInputStream, FileOutputStream, BufferedInputStream - 2 นี่คือการดำเนินการอ่านข้อมูลจากไฟล์โดยใช้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);
       }
   }
}
เราอ่านหนึ่งไบต์จากไฟล์ แปลงไบต์ที่อ่านเป็นอักขระและส่งออกไปยังคอนโซล และนี่คือผลลัพธ์ในคอนโซล:

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

คลาส BufferedInputStream

ฉันคิดว่าจากความรู้จากการบรรยายครั้งก่อนๆ คุณสามารถบอกได้ง่ายๆ ว่าทำไมจึงต้องมีคลาสBufferedInputStreamและมีข้อดีอะไรบ้างFileInputStream:) เราเจอบัฟเฟอร์สตรีมแล้ว ดังนั้นลองเดา (หรือจำ) ก่อนอ่านต่อ :) สตรีมบัฟเฟอร์ จำเป็นอย่างยิ่งสำหรับการปรับ I/O ให้เหมาะสมที่สุด การเข้าถึงแหล่งข้อมูล เช่น การอ่านจากไฟล์ เป็นการดำเนินการที่เน้นประสิทธิภาพ และการเข้าถึงไฟล์เพื่ออ่านครั้งละหนึ่งไบต์นั้นสิ้นเปลือง ดังนั้นจึงBufferedInputStreamอ่านข้อมูลไม่ใช่ทีละไบต์ แต่อ่านเป็นบล็อกและจัดเก็บไว้ในบัฟเฟอร์พิเศษชั่วคราว สิ่งนี้ช่วยให้เราเพิ่มประสิทธิภาพการทำงานของโปรแกรมโดยลดจำนวนการเข้าถึงไฟล์ มาดูกันว่ามีลักษณะอย่างไร:
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);
       }
   }
}
BufferedInputStreamที่นี่เราได้ สร้าง วัตถุ มันยอมรับวัตถุหรือตัวต่อๆ ไปเป็น input InputStreamดังนั้นอันก่อนหน้าFileInputStreamก็จะยอมรับ ใช้ขนาดบัฟเฟอร์เป็นไบต์เป็นพารามิเตอร์เพิ่มเติม ด้วยเหตุนี้ ข้อมูลจึงถูกอ่านจากไฟล์ ไม่ใช่ทีละไบต์ แต่ครั้งละ 200 ไบต์! ลองนึกภาพว่าเราลดจำนวนการเข้าถึงไฟล์ได้มากแค่ไหน เพื่อเปรียบเทียบประสิทธิภาพ คุณสามารถใช้ไฟล์ข้อความขนาดใหญ่หลายเมกะไบต์ และเปรียบเทียบระยะเวลาที่ใช้ในการอ่านและส่งออกไปยังคอนโซลในหน่วยมิลลิวินาทีโดยใช้FileInputStreamและ BufferedInputStreamนี่คือตัวอย่างโค้ดทั้งสอง:
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()));
   }
}
เมื่ออ่านไฟล์ขนาด 1.5 MB บนคอมพิวเตอร์ของฉันFileInputStreamมันทำงานได้ในเวลา ~3500 มิลลิวินาที แต่ที่นี่BufferedInputStreamมันทำงานได้ในเวลา ~1700 มิลลิวินาที อย่างที่คุณเห็น สตรีมบัฟเฟอร์ได้เพิ่มประสิทธิภาพการทำงานของโปรแกรมเป็น 2 เท่า! :) เราจะศึกษาคลาส I/O ต่อไป - แล้วพบกันใหม่!
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION