`fsetpos()` สามารถใช้เพื่ออนุญาตการเข้าถึงแบบสุ่มในไฟล์ที่มีขนาดใหญ่เกินกว่าจะจัดการกับ `fseek()` ได้อย่างไร

แม้ว่าฉันเข้าใจว่า fpos_t เป็นประเภททึบแสงที่ตั้งใจจะเริ่มต้นโดยฟังก์ชัน fgetpos() §7.19.9.1 ของ เหตุผล C99 ระบุว่า:

เพิ่ม fgetpos และ fsetpos ใน C89 เพื่ออนุญาตการเข้าถึงแบบสุ่มในไฟล์ที่มีขนาดใหญ่เกินกว่าจะจัดการกับ fseek และ ftell ได้

และ§7.19.9.2:

ความจำเป็นในการเข้ารหัสทั้งตำแหน่งบันทึกและตำแหน่งภายในบันทึกด้วยค่า long อาจจำกัดขนาดของไฟล์ข้อความซึ่งสามารถใช้ fseek และ ftell ให้มีขนาดเล็กกว่าขนาดของไฟล์ไบนารีได้อย่างมาก

...

เพิ่ม fgetpos และ fsetpos เพื่อจัดการกับไฟล์ที่มีขนาดใหญ่เกินกว่าจะจัดการกับ fseek และ ftell

ดูเหมือนว่าจะเน้นไปที่ไฟล์ข้อความเป็นหลัก (ไฟล์ที่เปิดด้วย mode ยกเว้นแฟล็ก b) เนื่องจากการใช้งานบางอย่างอาจจำเป็นต้องจัดเก็บสองตำแหน่ง (ตำแหน่งบันทึกไฟล์และตำแหน่งอักขระบันทึก) ซึ่งอาจลดช่วงที่มีประสิทธิภาพของ fseek() ได้อย่างมาก และฟังก์ชัน ftell() สำหรับการสตรีมข้อความ

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

ดูเหมือนว่าวิธีเดียวที่จะใช้ฟังก์ชันเหล่านี้ได้จริงคือการอ่านอักขระทุกตัวในไฟล์และแคชค่า fgetpos()d fpos_t ซึ่งดูดีที่สุด เนื่องจากคุณแทบไม่ต้องการอ่านที่ใกล้กับอักขระ LONG_MAX ตัวเลย

“คณะกรรมการ” คิดอะไรอยู่? มีเหตุผลเหตุผล C99 หรือไม่?


person gw0    schedule 31.03.2016    source แหล่งที่มา


คำตอบ (1)


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

ตัวอย่างเช่น หาก long มี 32 บิต ค่านี้อาจแบ่งออกเป็น 25 บิตสำหรับดัชนีบันทึก และ 7 บิตสำหรับตำแหน่งภายในบันทึก (อนุญาตให้มีความยาวบันทึกสูงสุดที่ใช้งานได้ 127 และ 2^25 ~= 33k บันทึก) อย่างไรก็ตาม ระบบอาจอนุญาตให้มีการบันทึกข้อมูลได้มากขึ้นเรื่อยๆ

(ข้อความข้างต้นเป็นความทรงจำที่คลุมเครือบางส่วน และอนุมานบางส่วนจากข้อความเหตุผล)

อย่างไรก็ตาม ปัญหาที่แท้จริงของ fseek และ ftell บนเดสก์ท็อปสมัยใหม่ก็คือค่า long อาจไม่เพียงพอที่จะแสดงถึงตำแหน่งไฟล์ทั้งหมด บนระบบ 32 บิต long มักจะเป็น 32 บิต แต่ไฟล์มักจะยังคงมีขนาดใหญ่กว่า 2GB ได้ ดังนั้นจึงจำเป็นต้องมีกลไกที่แตกต่างกันสำหรับการระบุออฟเซ็ตไฟล์

ฉันไม่เข้าใจว่าจะสามารถนำไปใช้กับ "การเข้าถึงแบบสุ่ม" อย่างมีประสิทธิภาพได้อย่างไร

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

person davmac    schedule 31.03.2016
comment
+1 แต่เมนเฟรมของ IBM ไม่ได้เก่าแก่ไปกว่า ASCII หรือ POSIX: www -03.ibm.com/systems/z/index.html - person Andrew Henle; 31.03.2016