بافر چیست و فلاش بکنیم یا نکنیم.

گاهی در مورد بافر در برنامه‌نویسی می‌شنویم، مثلا BufferedWriter در جاوا یا انواع و اقسام دیگری از ابزارهای خواندن/نوشتن که از بافر استفاده می‌کنن.

اکثر چیزهایی که خروجی‌ای رو توی فایل ذخیره می‌کنن از بافر استفاده می‌کنن. بافر چیه؟ یه حافظه موقت (که در دسترس مای استفاده کننده نیست) که کارش اینه که اون محتوایی که قراره نوشته بشه رو توی خودش ذخیره می‌کنه تا "زمانی که واقعا نوشته بشه"

پس فهمیدیم که ۲ تا حالت وجود داره

یکی اینکه ما دستور نوشتن رو بدیم، که اون چیزی که گفتیم نوشته بشه توی بافر سیو می‌شه.

دوم حالتی که واقعا نوشتن اتفاق بیافته و اصطلاحا بافر فلاش بشه.

این ۲ تا به صورت پایه از هم جدا هستن. اما چرا اصلا؟ خب همون موقع که دستور میدیم نوشته بشن.

داستان اینطوریه که چیزی که با دیسک/شبکه کار کنه "به شدت" کندتر از چیزیه که با رم/سی‌پی‌یو کار کنه. حالا ما وقتی دستور نوشتن می‌دیم همه چی توی رم/سی‌پی‌یو هندل می‌شه ولی اگر بخواد بنویسه اون موقع باید با دیسک/سوکت درگیر بشه که این برنامه رو کند می‌کنه. فرض اساسا بر اینه که شما چیزهای ریز ریز می‌نویسی و وقتی جمع شد دلت می خواد که همش با هم ارسال/سیو بشه، اینطوری کارایی خیلی بیشتر می‌شه.




حالا ما یه متد فلاش هم داریم که میاد و این بافر رو (به زور) خالی می‌کنه و عملیات نوشتن رو انجام می‌ده. اما همچنان اگه از فلاش استفاده نکنیم هم در نهایت نوشتن انجام می‌شه اما لزوما همون لحظه نیست. مثلا ما ممکنه 10 تا چیز write کنیم و فقط یه بار واقعا بافر خالی بشه.


حالا چه زمانی باید از فلاش استفاده کنیم و چه زمان نباید استفاده کنیم؟

زمانی که صرفا می‌خوایم یه سری چیز رو بنویسیم/بفرستیم و قرار نیست "به این زودی" خونده بشه، ما نیاز به فلاش نداریم. مثلا وقتی که می‌خوایم 10 تا آبجکت رو توی فایل سیو کنیم و بعدا مثلا بعد از همین فورمون یا فردا یا نیم ساعت دیگه اون رو لود کنیم و بخونیم، این نیاز به فلاش نداره. اون پارت آخر بافر هم همین که فایل رو بخوایم ببندیم سیو میشن و کلا لازم نیست خودمون رو نگران بافر و فلاش کنیم.

اما یه زمانی هست که وقتی ما چیزی رو می‌نویسیم واقعا دلمون می‌خواد نوشته بشه، مثلا وقتی که من الان دارم توی شبکه ارسال میکنم و اونور سرور منظر جواب منه و مثلا یه چت‌طور داریم. خب تو این مواقع ما حتما حتما باید فلاش کنیم چون سرور منتظره و اگر فلاش نکنیم اصلا چیزی نمی‌ره سمت سرور که سرور جواب بده و ما دوباره جواب بدیم بهش.


توی برنامه‌ای که پرفورمنس حیاتی نباشه اصولا می‌شه همیشه فلاش کرد، مثل اینه که اون بافره رو استفاده نمی‌کنیم در روند برنامه مشکلی پیش نمیاد. مشکل فقط وقتی به وجود میاد که باید فلاش کنیم مثل برنامه کلاینت و سرور ولی این کارو انجام ندیم.





یه مثال ملموس تر هم بزنم، ما وقتی که چیزی پرینت می‌کنیم هم در واقع داره بافر می‌شه و وقتی که newline مثل endl رو چاپ می‌کنیم در واقع این بافر فلاش می‌شه. می‌بینید که تقریبا یک ساله از بافر استفاده می‌کردید بدون اینکه نیاز باشه فلاشش کنید یا حتی ازش آگاه باشید. اما چه زمانی واقعا لازمه stdout رو فلاش کنید؟ زمانی که میخوایم یه نوشته رو تا وسط خط بنویسید و همونجا چاپ شه، نه اینکه منتظر بمونه برید خط بعد.


https://stackoverflow.com/questions/15042849/what-does-flushing-the-buffer-mean