การเขียนเมื่อเริ่มต้นไฟล์เป็นสิ่งที่คุณจะรู้ได้ในตอนท้าย


9

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

เมื่อฉันสามารถเก็บองค์ประกอบ EBML ทั้งหมดไว้ในหน่วยความจำจากนั้นสร้างเป็นเรื่องง่ายเพราะฉันสามารถย้อนกลับและเติมความยาวของแต่ละองค์ประกอบหลังจากที่ฉันรู้ว่าความยาวนั้นคืออะไร ปัญหาคือสิ่งที่ต้องทำเมื่อฉันไม่สามารถเก็บองค์ประกอบทั้งหมดไว้ในหน่วยความจำได้ ตัวเลือกที่ฉันเห็นคือ:

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

คำถาม:ดูเหมือนว่าสิ่งนี้น่าจะเป็นปัญหาที่คนทั่วไปคิดถึง ฉันรู้ว่ามันสามารถเกิดขึ้นได้เมื่อสร้าง data packets มีเทคนิคที่ดีขึ้น / มากกว่า / ที่ยอมรับมากกว่าฉันหายไปหรือเปล่า หรือเพียงแค่คำบางคำสำหรับปัญหาที่ฉันสามารถค้นหาได้


1
/ sccsทำงานด้วยวิธีนี้: มันเขียน checksum ของไบต์ทั้งหมดในตอนต้นของไฟล์หลังจากเขียนเสร็จแล้ว ใช้งานได้ดีกับ Unixes ที่สามารถใช้งานการดำเนินการไฟล์ตามต้องการ (เช่น Solaris) และทำให้เกิดปัญหาแปลก ๆ เกี่ยวกับ Unixes ที่ไม่สามารถทำได้เช่น Linux
gnat

คำตอบ:


2

หากคุณไม่ทราบว่าบรรทุกของคุณจะนานแค่ไหนนั่นเป็นสาเหตุที่ทำให้เกิดความกังวลแม้ว่าคุณจะไม่สามารถจำตำแหน่งและใส่ความยาวได้ในภายหลัง:

เพียงแค่จดบันทึก "ขนาดที่ไม่รู้จัก"

คุณลักษณะนั้นขึ้นอยู่กับส่วนของข้อมูลที่ประกอบด้วยองค์ประกอบ EBML และองค์ประกอบต่อไปนี้ไม่ได้เป็นองค์ประกอบลูกที่ถูกต้อง

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


อ้างถึงEBML RFC Draftบน matroska.org สำหรับรายละเอียด


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

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

เราใช้สคีมาของเราเองซึ่งจะขยายออก ได้รับการออกแบบโดยมีความรู้ว่าซอฟต์แวร์ตัวเก่าอาจต้องข้ามข้อมูลบางอย่างไป แต่นี่เป็นคุณสมบัติที่ยอดเยี่ยมของ EBML ที่ฉันไม่ทราบดังนั้นฉันจึงยอมรับคำตอบ
pscheidler

0

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

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

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

โดยทั่วไปแล้วพยายามลดจำนวนองค์ประกอบที่มีขนาดใหญ่ที่สุดให้น้อยที่สุด


เขาอาจทำเพื่อองค์ประกอบ EBML ของเขาเอง แต่ก็ยังไม่ช่วยเขาด้วยองค์ประกอบหลัก
Deduplicator

ความคิดของคุณจะใช้งานได้ แต่ฉันอยากจะสร้างระบบที่สามารถจัดการองค์ประกอบขนาดใหญ่แทนที่จะ จำกัด สคีมาเพื่อหลีกเลี่ยงองค์ประกอบขนาดใหญ่
pscheidler

วิธีการแก้ปัญหานี้จะทำงานสำหรับองค์ประกอบขนาดใหญ่เช่นกันเพียงระมัดระวังด้วยขนาดกองซ้อน และถ้าเป็นเรื่องของสคีมา ... ให้คิดว่ามันเป็นภาษาที่แอพพลิเคชั่นของคุณใช้อยู่ถ้าหากไม่สามารถจัดการกับสิ่งที่ซับซ้อนได้อีกอย่างหนึ่งก็ควรที่จะปรับตัวหรือต้องการนักแปล นักพัฒนาหลายคน (อย่างน้อย C / C ++ ที่ฉันรู้) มักจะหลีกเลี่ยงการเปลี่ยนแปลงแบบแผน / การออกแบบเหมือนเป็นไฟซึ่งต่อมาส่งผลให้ระบบไม่ดี หากส่วนประกอบอื่นไม่สามารถปรับได้แสดงว่าอาจมีการย่อยสลาย / ออกแบบมาไม่ดี หากมีเหตุผลอื่น ๆ ที่ไม่เปลี่ยนแปลงคุณควรพิจารณาการใช้ฮาร์ดแวร์ที่แตกต่าง
Whoot

0

KISS และ YAGNI
เลือกตัวเลือก # 1 และถ้ามันกลายเป็นปัญหาจริง - จากนั้นให้คำแนะนำกับมันอีกครั้ง

อย่างน้อยสำหรับกรณีการใช้งานที่คล้ายกันที่มีรูปแบบไบนารีที่คล้ายกันเมื่อมีค่าเพียงสองสามค่าที่ต้องเติมในลักษณะนี้นี่เป็นวิธีที่ง่ายที่สุด / ง่ายที่สุด / ดีที่สุด ถ้าคุณต้องทำสิ่งนี้กับข้อมูลแต่ละอัน - มันอาจเป็นข้อบกพร่องในสถาปัตยกรรม

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