ไฟล์โครงการ Visual Studio 2008 ไม่โหลดเนื่องจากการเปลี่ยนแปลงการเข้ารหัสที่ไม่คาดคิด

ในทีมของเรา เรามีโครงการฐานข้อมูลใน Visual Studio 2008 ซึ่งอยู่ภายใต้การควบคุมแหล่งที่มาโดย Team Foundation Server ทุกสองสัปดาห์โดยประมาณ หลังจากที่เพื่อนร่วมงานคนหนึ่งเช็คอิน ไฟล์โปรเจ็กต์จะไม่โหลดบนเครื่องของนักพัฒนารายอื่น ข้อความแสดงข้อผิดพลาดคือ:

ไม่สามารถโหลดไฟล์โครงการได้ ข้อมูลในระดับรากไม่ถูกต้อง บรรทัดที่ 1 ตำแหน่งที่ 1

เมื่อฉันดูไฟล์โครงการใน Notepad++ ไฟล์จะมีลักษณะดังนี้:

��<NUL?NULxNULmNULlNUL NULvNULeNULrNULsNULiNULoNULnNUL ...

และอื่นๆ (คุณสามารถเห็น <?xml version ในนี้) ในขณะที่ไฟล์โปรเจ็กต์ปกติจะมีลักษณะดังนี้:

<?xml version="1.0" encoding="utf-16"?> ...

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

ตามไฟล์ การเข้ารหัสควรเป็น UTF-16 ตาม Notepad++ ไฟล์ที่เสียหายคือ UTF-8 จริงๆ

คำถามของฉันคือ:

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

ตามหมายเหตุล่าสุด: ปัญหาอยู่ที่ไฟล์โปรเจ็กต์เดียว ไฟล์โปรเจ็กต์อื่นๆ ทั้งหมดไม่ทำให้เกิดปัญหานี้

อัปเดต: ขอบคุณคำแนะนำของ Jon Skeet ฉันมีคำตอบสำหรับคำถามข้อที่สาม เมื่อฉันแทนที่เก้าไบต์แรก EF BB BF EF BF BD EF BF BD ด้วยสองไบต์ FF FE ไฟล์โปรเจ็กต์จะโหลดอีกครั้ง

นี่ยังคงเป็นคำถามว่าทำไม Visual Studio ทำให้ไฟล์เสียหาย


person Xenan    schedule 23.03.2010    source แหล่งที่มา
comment
คุณเห็นอะไรถ้าคุณทำไบนารี่ดิฟชั่นระหว่างไฟล์ที่เสียหายและไฟล์ที่ใช้งานได้? ฉันสงสัยว่ามันเป็นปัญหา endianness UTF-16 หรือไม่   -  person Jon Skeet    schedule 23.03.2010
comment
หากฉันทำไบนารี่ดิฟเฟอเรนเชียล ปรากฎว่าไฟล์นั้นมีลักษณะเยื้อง ยกเว้นว่าไฟล์ที่ถูกต้องจะมีไบต์พิเศษสองไบต์ที่จุดเริ่มต้น FF FE และไฟล์ที่เสียหายมีไบต์พิเศษเก้าไบต์ EF BB BF EF BF BD EF BF BD   -  person Xenan    schedule 23.03.2010


คำตอบ (1)


ฉันคิดว่าฉันสามารถให้ข้อมูลเชิงลึกเกี่ยวกับสิ่งที่เกิดขึ้นได้ หากไม่ใช่เพราะเหตุใด

FF FE คือ BOM; การมีอยู่ที่จุดเริ่มต้นของไฟล์บ่งชี้ว่าการเข้ารหัสของไฟล์นั้นเป็น UTF-16 ซึ่งเป็น little-endian และดูเหมือนว่าไฟล์ต้นฉบับจะเป็น UTF-16 จริงๆ แต่มีบางอย่างเพิกเฉยต่อ BOM และอ่านมันราวกับว่าเป็น UTF-8

เมื่อเกิดเหตุการณ์เช่นนี้ แต่ละไบต์ FF และ FE จะถือว่าไม่ถูกต้องและแปลงเป็น U+FFFD ซึ่งเป็นอักขระขยะ Unicode อย่างเป็นทางการ จากนั้น เมื่อข้อความถูกเขียนลงในไฟล์อีกครั้ง อักขระขยะแต่ละตัวจะถูกแปลงเป็นการเข้ารหัส UTF-8 (EF BF BD) และเพิ่ม UTF-8 BOM (EF BB BF) ไว้ข้างหน้าอักขระเหล่านั้น ผลลัพธ์ที่ได้คือลำดับเก้าไบต์ที่คุณรายงาน:

EF BB BF  # UTF-8 BOM
EF BF BD  # U+FFFD in UTF-8
EF BF BD  # ditto

ในกรณีนี้ การแทนที่ไบต์ทั้งเก้าด้วย FF FE นั้นไม่ปลอดภัย ไม่มีการรับประกันว่าจะเป็นไบต์เดียวในไฟล์ที่จะไม่ถูกต้องเมื่อแปลเป็น UTF-8 ตราบใดที่ไฟล์มีเพียงอักขระ ASCII คุณก็ไม่เป็นไร แต่อย่างอื่น เช่น อักขระเน้นเสียง (é) หรือเครื่องหมายคำพูดแบบโค้ง () จะถูกทำให้เสียหายอย่างไม่อาจแก้ไขได้

ไฟล์โปรเจ็กต์ควรจะเป็น UTF-16 จริงๆ หรือไม่ ถ้าไม่เช่นนั้น อาจเป็นไปได้ว่าระบบของนักพัฒนารายหนึ่งกำลังสร้าง UTF-16 เมื่อระบบควบคุมเวอร์ชันคาดว่าจะเป็น UTF-8 ฉันสังเกตเห็นในการติดตั้ง Visual C# Express ของฉันมีตัวเลือกภายใต้ Environment->Documents ชื่อ "บันทึกเอกสารเป็น Unicode เมื่อข้อมูลไม่สามารถบันทึกในเพจโค้ด" ฟังดูเหมือนเป็นสิ่งที่อาจทำให้การเข้ารหัสเปลี่ยนแปลงในเวลาสุ่มอย่างเห็นได้ชัด

person Alan Moore    schedule 24.03.2010
comment
ขอบคุณครับ เรื่องนี้ให้ข้อมูลเชิงลึกจริงๆ - person Xenan; 25.03.2010