Java Files.move กับ ATOMIC_MOVE: เผยแพร่ไฟล์เมื่อเขียนเสร็จทั้งก้อน
ถ้าเขียน config หรือ report ลงชื่อจริงทีละ byte ผู้อ่านอีก process อาจเห็นไฟล์ครึ่งก้อนครับ รูปแบบที่ปลอดภัยกว่าคือเขียนไฟล์ชั่วคราวให้เสร็จ ปิด handle แล้วใช้ Files.move พร้อม ATOMIC_MOVE เพื่อให้การเปลี่ยนชื่อปรากฏเป็นจังหวะเดียวเมื่อ filesystem รองรับ
เหมือนเตรียมแฟ้มหลังเคาน์เตอร์จนเรียบร้อย แล้วสอดเข้า slot เผยแพร่ครั้งเดียว คนอ่านจะเห็นแฟ้มเก่าหรือแฟ้มใหม่ ไม่ควรเห็นหน้ากระดาษที่ยังเย็บไม่ครบ
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
public class Main {
public static void main(String[] args) throws Exception {
Path dir = Files.createTempDirectory("atomic-publish-");
Path draft = dir.resolve("report.tmp");
Path published = dir.resolve("report.txt");
try {
Files.writeString(draft, "complete", StandardCharsets.UTF_8);
Files.move(draft, published, StandardCopyOption.ATOMIC_MOVE);
assert Files.notExists(draft);
assert Files.readString(published, StandardCharsets.UTF_8).equals("complete");
System.out.println("atomic move test passed");
} finally {
Files.deleteIfExists(draft);
Files.deleteIfExists(published);
Files.deleteIfExists(dir);
}
}
}
Atomic มีขอบเขต
JDK ระบุว่า provider อาจยก AtomicMoveNotSupportedException เช่นย้ายข้าม filesystem ดังนั้นไฟล์ชั่วคราวควรอยู่ directory เดียวกับปลายทาง หาก fallback เป็น move ธรรมดา ต้องยอมรับและบันทึกว่า atomicity หายไป หรือเลือก fail-closed เมื่อไฟล์นี้เป็น boundary สำคัญ
เมื่อใช้ ATOMIC_MOVE behavior ตอนปลายทางมีอยู่เป็น implementation-specific และ option อื่นถูกละเลยตาม contract อย่าสมมติว่า REPLACE_EXISTING จะกำหนดผลร่วมกันได้ทุก provider หากต้องไม่ overwrite ให้ทำชื่อปลายทาง unique หรือใช้ primitive/lock ที่สัญญาตรงกับ storage นั้น และอย่าลืม durability: atomic visibility ไม่ได้แปลว่าข้อมูลถูก flush ลงสื่อถาวรแล้วทุกชั้น
Recap
- เขียนและปิดไฟล์ชั่วคราวก่อน publish
- วาง temp บน filesystem เดียวกับปลายทาง
- จัดการ
AtomicMoveNotSupportedExceptionตามระดับความเสี่ยง - แยก atomic visibility ออกจาก overwrite policy และ durability