จุดประสงค์ของการล้าง () ในสตรีม Java คืออะไร?


121

ใน Java flush()ใช้วิธีการในสตรีม แต่ฉันไม่เข้าใจว่าจุดประสงค์ของการใช้วิธีนี้คืออะไร?

fin.flush();

บอกคำแนะนำหน่อย

คำตอบ:


101

จากเอกสารของflushวิธีการ:

ล้างสตรีมเอาต์พุตและบังคับให้เขียนไบต์เอาต์พุตที่บัฟเฟอร์ สัญญาทั่วไปของการล้างคือการเรียกมันเป็นการบ่งชี้ว่าหากไบต์ใด ๆ ที่เขียนไว้ก่อนหน้านี้ถูกบัฟเฟอร์โดยการนำเอาท์พุทสตรีมไปใช้งานไบต์ดังกล่าวควรถูกเขียนไปยังปลายทางที่ต้องการทันที

การบัฟเฟอร์ส่วนใหญ่ทำเพื่อปรับปรุงประสิทธิภาพ I / O เพิ่มเติมเกี่ยวกับเรื่องนี้สามารถอ่านได้จากบทความนี้: ปรับแต่ง Java I / O ที่ผลการดำเนินงาน


1
ลิงก์ใหม่สำหรับ Tuning Java I / O Performance oracle.com/technetwork/articles/javase/perftuning-137844.html
Oleksandr

+1 ขอบคุณครับ ฉันคิดไม่ออกว่าทำไมไบต์ของฉันถึงไม่ถูกส่งออกไปและนั่นเป็นเพราะฉันต้องล้างบัฟเฟอร์
rayryeng

3
วิธีการล้างใช้กับสตรีมบัฟเฟอร์เท่านั้นหรือไม่ มีข้อได้เปรียบในการใช้กับสตรีมอื่น ๆ (เช่นเอาต์พุตสตรีม) ด้วยหรือไม่?
tnishada

บางทีคำว่า 'ล้าง' ไม่ควรอยู่ในความหมาย คำจำกัดความแบบวนซ้ำเป็นความคิดที่ไม่ดีสำหรับการทำความเข้าใจสิ่งใหม่ ๆ ฉันทราบว่าคุณไม่ได้เขียนคำจำกัดความ
Jonathan Komar

27

เมื่อเราให้คำสั่งสตรีมของคำสั่งนั้นจะถูกเก็บไว้ในตำแหน่งหน่วยความจำที่เรียกว่าบัฟเฟอร์ (ตำแหน่งหน่วยความจำชั่วคราว) ในคอมพิวเตอร์ของเรา เมื่อตำแหน่งหน่วยความจำชั่วคราวทั้งหมดเต็มเราจะใช้ flush () ซึ่งจะล้างสตรีมข้อมูลทั้งหมดและดำเนินการอย่างสมบูรณ์และให้พื้นที่ใหม่แก่สตรีมใหม่ในตำแหน่งชั่วคราวบัฟเฟอร์ - หวังว่าคุณจะเข้าใจ


1
เฉพาะในกรณีของBufferedOutputStream, BufferedWriter, ObjectOutputStream,และPrintXXXชั้นเรียน flush()วิธีการสตรีมอื่น ๆ หรือWriterไม่ทำอะไรเลย
Marquis of Lorne

@EJP การอ้างอิงใด ๆ ในการสำรองข้อมูลงบของคุณ? จะเป็นประโยชน์สำหรับพวกเรามือใหม่ :)
mr5

1
@ mr5 เป็นผู้โพสต์ที่ต้องสำรองข้อมูลของเขาไม่ใช่ฉัน แต่ทุกอย่างที่ฉันพูดมีระบุไว้อย่างชัดเจนใน Javadoc
Marquis of Lorne

flush()ไม่จำเป็นต้องเรียกอย่างชัดเจนสำหรับ a BufferedWriterตราบใดที่คุณclose()เป็นนักเขียน close()ดำเนินการล้างตัวเอง
Yossarian42

บันทึกการclose()โทรflush()ดังนั้นการโทรทั้งสองจะซ้ำซ้อนเมื่อใช้FileWriterโดยไม่มีบัฟเฟอร์
Yossarian42

26

เมื่อคุณเขียนข้อมูลไปยังสตรีมข้อมูลจะไม่ถูกเขียนในทันทีและจะถูกบัฟเฟอร์ ดังนั้นใช้flush()เมื่อคุณต้องการให้แน่ใจว่าข้อมูลทั้งหมดของคุณจากบัฟเฟอร์ถูกเขียน

เราจำเป็นต้องให้แน่ใจว่าเขียนทั้งหมดจะเสร็จสมบูรณ์ก่อนที่เราจะปิดกระแสและนั่นคือเหตุผลที่flush()เรียกว่าในไฟล์ / close()นักเขียนของบัฟเฟอร์

flush()แต่ถ้าคุณมีความต้องการที่ทุกเขียนของคุณจะถูกบันทึกไว้ได้ตลอดเวลาก่อนที่คุณปิดกระแสการใช้งาน


8
การเรียกฟลัชก่อนปิดซ้ำซ้อนใช่ไหม? ก็เหมือนกับการเรียกปิด
John Henckel

2
@BimanTripathy บอกได้เลยว่ามั่นใจได้ 100% มันมีการประกันโดย Javadoc ของและFilterOutputStream FilterWriter
Marquis of Lorne

7

หากบัฟเฟอร์เต็มสตริงทั้งหมดที่ถูกบัฟเฟอร์ไว้สตริงเหล่านั้นจะถูกบันทึกลงในดิสก์ บัฟเฟอร์ใช้เพื่อหลีกเลี่ยงจากข้อเสนอพิเศษ! และค่าใช้จ่าย

ในคลาส BufferedWriter ที่อยู่ใน java libs มีบรรทัดเดียวเช่น:

private static int defaultCharBufferSize = 8192;

หากคุณไม่ต้องการส่งข้อมูลก่อนที่บัฟเฟอร์จะเต็มคุณจะสามารถควบคุมได้ เพียงแค่ล้างมัน โทรไปที่ writer.flush () พูดว่า "ส่งอะไรก็ได้ในบัฟเฟอร์เดี๋ยวนี้!

หนังสืออ้างอิง: https://www.amazon.com/Head-First-Java-Kathy-Sierra/dp/0596009208

หน้า: 453


4

สตรีมมักจะเข้าถึงได้โดยเธรดที่ว่างเนื้อหาเป็นระยะ ๆ และตัวอย่างเช่นแสดงบนหน้าจอส่งไปยังซ็อกเก็ตหรือเขียนลงในไฟล์ สิ่งนี้ทำด้วยเหตุผลด้านประสิทธิภาพ การล้างสตรีมเอาท์พุตหมายความว่าคุณต้องการหยุดรอให้เนื้อหาของสตรีมถูกโอนไปยังปลายทางอย่างสมบูรณ์จากนั้นดำเนินการต่อโดยที่สตรีมว่างเปล่าและเนื้อหาที่ส่ง


5
นี่คือแฟนตาซี สตรีมไม่สามารถเข้าถึงได้โดยเธรดเวทย์มนตร์ใด ๆ เฉพาะที่สร้างโดยแอปพลิเคชัน
Marquis of Lorne

3

สำหรับปัญหาด้านประสิทธิภาพข้อมูลแรกจะถูกเขียนลงในบัฟเฟอร์ เมื่อบัฟเฟอร์เต็มข้อมูลจะถูกเขียนไปยังเอาต์พุต (ไฟล์คอนโซล ฯลฯ ) เมื่อบัฟเฟอร์ถูกเติมบางส่วนและคุณต้องการส่งไปยังเอาต์พุต (ไฟล์คอนโซล) คุณต้องเรียกใช้เมธอด flush () ด้วยตนเองเพื่อเขียนบัฟเฟอร์ที่เติมบางส่วนไปยังเอาต์พุต (ไฟล์คอนโซล)


นี่ไม่เป็นความจริง. FileOutputStream.flush () คือ no-op ว่างเปล่า
vertuso
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.