ข้ามไปเนื้อหาหลัก

เขียนไฟล์ JSON ทับที่เดิมอันตรายไหม: เทคนิคเขียนโค้ดไม่ให้พัง

เจาะลึกปัญหาเขียนไฟล์ JSON แบบเปิดช่องให้คนอ่านเจอข้อมูลครึ่งๆ กลางๆ พร้อมวิธีแก้ด้วย temp file, os.replace และ os.fsync ใน Python

เรียบเรียงโดย AI
Inewgen
23 Oct 2026ที่มา: Dev.to3 นาทีอ่าน (0 ครั้ง)
แชร์
เขียนไฟล์ JSON ทับที่เดิมอันตรายไหม: เทคนิคเขียนโค้ดไม่ให้พัง

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ขนาดตัวอักษร
  • การเขียนไฟล์ JSON ทับที่เดิมตรงๆ เสี่ยงทำให้โปรแกรมอ่านเจอไฟล์ว่างหรือพัง
  • การใช้ temp file ร่วมกับ os.replace ช่วยให้อ่านไฟล์ได้สมบูรณ์แบบ atomic operation
  • ต้องสร้างไฟล์ชั่วคราวในโฟลเดอร์เดียวกันเพื่อป้องกันปัญหาคนละ filesystem
  • อย่าลืมซิงค์ข้อมูลลงดิสก์ด้วย os.fsync เพื่อป้องกันการสูญหายยามระบบล่ม

นักพัฒนาหลายคนอาจคุ้นเคยกับการเขียนไฟล์ข้อมูลด้วยคำสั่งเปิดไฟล์ธรรมดา เช่น with open(PATH, 'w') เพื่อบันทึกข้อมูลใหม่ลงไปทับไฟล์เดิมทันที แต่รู้หรือไม่ว่าวิธีนี้อาจซ่อนปัญหาใหญ่เอาไว้ หากมีกระบวนการอื่นพยายามเข้ามาอ่านไฟล์นั้นในจังหวะที่ไฟล์กำลังถูกเขียนซ้ำพอดี โปรแกรมอ่านจะเจอข้อผิดพลาดประเภทรวมถึง JSONDecodeError ทันที เนื่องจากไฟล์ถูกล้างข้อมูลจนว่างเปล่าแต่ยังเขียนข้อมูลชุดใหม่ไม่เสร็จสิ้น

จากการทดสอบบนสภาพแวดล้อม Linux ที่ใช้ Python 3.10.12 พบว่าปัญหาดังกล่าวไม่ได้เกิดขึ้นได้ยากอย่างที่คิด ขนาดของไฟล์ที่ใหญ่ขึ้นยิ่งเพิ่มช่องว่างให้โปรแกรมอ่านเข้ามาสุ่มเจอจังหวะที่ไฟล์ไม่สมบูรณ์ได้ง่ายยิ่งขึ้น และหากกระบวนการเขียนถูกตัดจบกะทันหันด้วยคำสั่ง SIGKILL ไฟล์จะเสียหายคาอยู่แบบนั้นจนกว่าจะมีรอบเขียนใหม่มาทับ

code editor programming screen closeup

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

แนวทางแก้ไขที่ถูกต้องคือการเขียนข้อมูลใหม่ลงในไฟล์ชั่วคราว (temporary file) ให้เสร็จสมบูรณ์เสียก่อน จากนั้นจึงใช้คำสั่งเปลี่ยนชื่อไฟล์เพื่อสับเปลี่ยนกับไฟล์เดิมในขั้นตอนเดียวตามข้อกำหนด POSIX ของฟังก์ชัน os.replace ซึ่งรับประกันว่าโปรแกรมอ่านจะเห็นแค่ไฟล์เก่าหรือไฟล์ใหม่แบบเต็มๆ เท่านั้น ไม่มีทางเห็นข้อมูลครึ่งๆ กลางๆ

ไม่อยากพลาดข่าวใหม่?

สมัครรับสรุปข่าวสารใหม่ทางอีเมล ไม่บ่อยจนรำคาญ

โฆษณา

3.10.12เวอร์ชัน Python ที่ใช้ทดสอบ
3กับดักหลักที่ต้องระวังในการทำไฟล์ชั่วคราว

อย่างไรก็ตาม การใช้งานเทคนิคนี้ยังมีกับดักสำคัญที่นักพัฒนาต้องระวัง:

  • ระวังเรื่อง Filesystem ต่างกัน: การเรียกใช้งาน tempfile.mkstemp() โดยไม่ระบุโฟลเดอร์ ระบบจะเลือกใช้ไดเรกทอรีชั่วคราวกลาง ซึ่งบนเครื่องทดสอบพบว่า /tmp และโฟลเดอร์โปรเจกต์อยู่คนละดิสก์กัน ทำให้คำสั่ง os.replace ล้มเหลว การสร้างไฟล์ชั่วคราวในโฟลเดอร์เป้าหมายโดยตรงจึงปลอดภัยที่สุด
  • สิทธิ์การเข้าถึงไฟล์ถูกจำกัด: ฟังก์ชัน mkstemp จะสร้างไฟล์ที่มีสิทธิ์ให้เจ้าของอ่านและเขียนได้เท่านั้น จึงต้องคัดลอกโหมดเดิมของไฟล์เก่ามาใส่ด้วยคำสั่ง os.chmod เสมอ
  • ปัญหาเรื่อง Symlink และ Hard Link: หากไฟล์เป้าหมายเป็น Symlink การแทนที่ไฟล์จะเปลี่ยนเป้าหมายของลิงก์ ส่วน Hard link จะยังคงชี้ไปยังเนื้อหาชุดเก่าเหมือนเดิม

การทำ Atomic Write ถือเป็นหัวใจสำคัญในการพัฒนาซอฟต์แวร์ที่ต้องจัดการกับสถานะ (State) ของข้อมูลในรูปแบบไฟล์ เนื่องจากระบบปฏิบัติการสมัยใหม่มักจะมีการแคชข้อมูลไว้ในหน่วยความจำชั่วคราว การใช้ฟังก์ชันอย่าง os.fsync() ทั้งกับไฟล์และไดเรกทอรีจึงเป็นปราการด่านสุดท้ายที่ช่วยบังคับให้ข้อมูลถูกเขียนลงสู่ฮาร์ดดิสก์จริงๆ ป้องกันไฟล์พังยามเกิดไฟดับหรือระบบล่มกะทันหัน

linux terminal command line interface

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ที่มา: Dev.to

ความคิดเห็น

แสดงความคิดเห็น
0/2000

พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้