โค้ดยิม/จาวาบล็อก/สุ่ม/อินพุต/เอาต์พุตในภาษาจาวา คลาส FileInputStream, FileOutpu...
John Squirrels
ระดับ
San Francisco

อินพุต/เอาต์พุตในภาษาจาวา คลาส FileInputStream, FileOutputStream และ BufferedInputStream

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

คลาส FileOutputStream

จุดประสงค์หลักของFileOutputStreamคลาสคือการเขียนไบต์ลงในไฟล์ ไม่มีอะไรซับซ้อน :) FileOutputStreamเป็นหนึ่งในการใช้งานของOutputStreamคลาสนามธรรม ในคอนสตรัคเตอร์ วัตถุของคลาสนี้ใช้พาธไปยังไฟล์เป้าหมาย (ซึ่งควรเขียนไบต์) หรือ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 CodeGym — The best site for would-be programmers!";

       fileOutputStream.write(greetings.getBytes());
       fileOutputStream.close();
   }
}
เมื่อสร้างFileวัตถุ เราส่งเส้นทางที่ต้องการไปยังตัวสร้าง เราไม่จำเป็นต้องสร้างมันล่วงหน้า ถ้าไม่มี โปรแกรมจะสร้างมันขึ้นมา คุณยังสามารถได้รับโดยไม่ต้องสร้างวัตถุเพิ่มเติม เพียงแค่ส่งสตริงที่มีเส้นทาง:
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();
   }
}
ผลลัพธ์ในทั้งสองกรณีจะเหมือนกัน เราสามารถเปิดไฟล์ของเราและดูสิ่งต่อไปนี้:
Hi! Welcome to CodeGym — The best site for would-be programmers!
แต่มีความแตกต่างกันเล็กน้อยที่นี่ ลองเรียกใช้โค้ดจากตัวอย่างด้านบนหลายๆ ครั้งติดต่อกัน จากนั้นดูในไฟล์และตอบคำถามนี้: มีกี่บรรทัด แค่หนึ่ง. แต่คุณรันโค้ดหลายครั้ง ปรากฎว่าข้อมูลถูกเขียนทับทุกครั้ง ข้อมูลเก่าจะถูกแทนที่ด้วยข้อมูลใหม่ เราจะทำอย่างไรถ้าไม่เหมาะกับเราและเราต้องเขียนไฟล์ตามลำดับ? ถ้าเราต้องการเขียนคำทักทายลงในไฟล์ 3 ครั้งติดต่อกันล่ะ? ทุกอย่างง่ายมาก เนื่องจากภาษาไม่สามารถรู้ได้ว่าเราต้องการพฤติกรรมใดในแต่ละกรณีFileOutputStreamผู้เชื่อมโยงสามารถใช้พารามิเตอร์เพิ่มเติมได้ —boolean append. ถ้าค่าเป็นจริง ข้อมูลจะถูกเขียนต่อท้ายไฟล์ หากเป็นเท็จ (และโดยค่าเริ่มต้นจะเป็นเท็จ) ข้อมูลเก่าจะถูกลบและแทนที่ด้วยข้อมูลใหม่ ตรวจสอบสิ่งนี้โดยรันโค้ดที่แก้ไขของเราสามครั้ง:
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();
   }
}
เนื้อหาไฟล์:
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!
ตอนนี้มันแตกต่างกันแล้ว! อย่าลืมคุณลักษณะนี้เมื่อใช้คลาส I/O มีช่วงหนึ่งที่ฉันใช้เวลาทำงานหลายชั่วโมง ใช้สมองเป็นชั่วโมง พยายามทำความเข้าใจว่าข้อมูลของฉันหายไปจากไฟล์ได้อย่างไร :) และแน่นอน เช่นเดียวกับคลาส I/O อื่นๆ อย่าลืมใช้close()วิธี เพื่อทรัพยากรฟรี

คลาส FileInputStream

The 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"
อินพุต/เอาต์พุตในภาษาจาวา  คลาส 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วัตถุ คอนสตรัคเตอร์ใช้อินสแตนซ์ของ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 มิลลิวินาที อย่างที่คุณเห็น สตรีมที่บัฟเฟอร์ได้เพิ่มประสิทธิภาพการทำงาน โดยลดไปครึ่งหนึ่ง! :) เราจะเรียนคลาส I/O กันต่อ — แล้วพบกันใหม่!
ความคิดเห็น
  • เป็นที่นิยม
  • ใหม่
  • เก่า
คุณต้องลงชื่อเข้าใช้เพื่อแสดงความคิดเห็น
หน้านี้ยังไม่มีความคิดเห็นใด ๆ