คำอธิบายทางเทคนิค
สาเหตุที่วิธีการส่วนใหญ่ก่อให้เกิดปัญหาคือ Windows พยายามระบุไฟล์และโฟลเดอร์ นี้ไม่ได้เป็นปัญหามากมีไม่กี่ร้อยหรือแม้กระทั่งพันไฟล์ / โฟลเดอร์ระดับไม่กี่ลึก แต่เมื่อคุณมีล้านล้านของไฟล์ในโฟลเดอร์นับล้านไปหลายสิบของระดับลึก ๆ แล้วที่แน่นอนจะชะงักลงระบบ .
ให้คุณมีไฟล์“ เพียง” 100,000,000 ไฟล์และ Windows ใช้โครงสร้างอย่างง่ายเช่นนี้ในการจัดเก็บแต่ละไฟล์พร้อมกับพา ธ ของไฟล์ (วิธีที่คุณหลีกเลี่ยงการจัดเก็บแต่ละไดเรกทอรีแยกต่างหากจึงช่วยประหยัดค่าใช้จ่าย)
struct FILELIST { // Total size is 264 to 528 bytes:
TCHAR name[MAX_PATH]; // MAX_PATH=260; TCHAR=1 or 2 bytes
FILELIST* nextfile; // Pointers are 4 bytes for 32-bit and 8 for 64-bit
}
ขึ้นอยู่กับว่าจะใช้อักขระ 8 บิตหรืออักขระ Unicode (ใช้ Unicode) และระบบของคุณเป็น 32- บิตหรือ 64- บิตจากนั้นจะต้องมีหน่วยความจำระหว่าง 25GB ถึง 49GB เพื่อเก็บรายการ (และนี่เป็นสิ่งที่ดีมาก โครงสร้างที่เรียบง่าย)
เหตุผลที่ว่าทำไม Windows พยายามที่จะระบุไฟล์และโฟลเดอร์ก่อนที่จะลบพวกเขาแตกต่างกันไปขึ้นอยู่กับวิธีที่คุณใช้เพื่อที่จะลบ แต่ทั้งสอง Explorer และคำสั่งล่ามทำมัน (คุณสามารถดูล่าช้าเมื่อคุณเริ่มต้นคำสั่ง) นอกจากนี้คุณยังสามารถดูไฟกิจกรรมดิสก์ (LED HDD) ในขณะที่อ่านแผนผังไดเรกทอรีจากไดรฟ์
วิธีการแก้
วิธีที่ดีที่สุดในการจัดการกับสถานการณ์เช่นนี้คือการใช้เครื่องมือลบที่ลบไฟล์และโฟลเดอร์ทีละรายการทีละครั้ง ฉันไม่รู้ว่ามีเครื่องมือสำเร็จรูปใด ๆ ที่ต้องทำหรือไม่ แต่ควรเป็นไปได้ด้วยไฟล์แบตช์แบบง่าย
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
สิ่งนี้ใช้เพื่อตรวจสอบว่ามีการโต้แย้งหรือไม่ ถ้าเป็นเช่นนั้นมันจะเปลี่ยนไดเรกทอรีที่ระบุ (คุณสามารถเรียกใช้โดยไม่มีอาร์กิวเมนต์ให้เริ่มในไดเรกทอรีปัจจุบันหรือระบุไดเรกทอรี - แม้ในไดรฟ์อื่นเพื่อเริ่มต้นที่นั่น)
ถัดไปมันจะลบไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน ในโหมดนี้ไม่ควรระบุอะไรและเพียงแค่ลบไฟล์โดยไม่ดูดหน่วยความจำถ้ามี
จากนั้นมันจะแจกแจงโฟลเดอร์ในไดเรกทอรีปัจจุบันและเรียกตัวเองผ่านแต่ละโฟลเดอร์ไปยัง (ตัวเอง) เพื่อย่อค่าลง
การวิเคราะห์
ด้วยเหตุผลที่ว่านี้ควรทำงานเป็นเพราะมันไม่ได้ระบุทุกไฟล์เดียวและโฟลเดอร์ในต้นไม้ทั้งหมด มันไม่ได้ระบุไฟล์ใด ๆ เลยและระบุเฉพาะโฟลเดอร์ในไดเรกทอรีปัจจุบัน (รวมถึงไฟล์ที่เหลืออยู่ในไดเรกทอรีหลัก) สมมติว่ามีไดเรกทอรีย่อยเพียงไม่กี่ร้อยไดเรกทอรีในโฟลเดอร์ใด ๆ ก็ตามนี่ไม่ควรเลวร้ายเกินไปและต้องใช้หน่วยความจำน้อยกว่าวิธีอื่น ๆ ที่ระบุทั้งแผนผัง
คุณอาจสงสัยเกี่ยวกับการใช้/r
สวิตช์แทนการใช้การสอบถามซ้ำแบบแมนนวล ที่จะไม่ทำงานเพราะในขณะที่/r
สวิตช์จะเรียกซ้ำมัน pre- ระบุต้นไม้ไดเรกทอรีทั้งหมดซึ่งเป็นสิ่งที่เราต้องการหลีกเลี่ยง; เราต้องการลบเมื่อเราไปโดยไม่ติดตาม
การเปรียบเทียบ
ให้เปรียบเทียบวิธีนี้กับวิธีการแจงนับเต็ม
คุณบอกว่าคุณมี“ ไดเรกทอรีนับล้าน”; สมมุติว่า 100 ล้าน หากทรีมีความสมดุลโดยประมาณและสมมติว่ามีค่าเฉลี่ยประมาณ 100 ไดเรกทอรีย่อยต่อโฟลเดอร์ไดเรกทอรีที่ซ้อนกันที่ลึกที่สุดจะอยู่ที่ประมาณสี่ระดับ - จริง ๆ แล้วจะมีโฟลเดอร์ย่อย 101,010,100 โฟลเดอร์ในต้นไม้ทั้งหมด (น่าขบขันว่า 100M สามารถแยกย่อยได้เพียง 100 และ 4)
เนื่องจากเราไม่ได้แจกแจงไฟล์เราจะต้องติดตามชื่อไดเรกทอรีไม่เกิน 100 ชื่อต่อระดับเพื่อสูงสุด4 × 100 = 400
ไดเรกทอรีในเวลาใดก็ตาม
ดังนั้นความต้องการของหน่วยความจำควรเป็น ~ 206.25KB ภายในขอบเขตของระบบที่ทันสมัย (หรืออย่างอื่น)
ทดสอบ
น่าเสียดายที่ (?) ฉันไม่มีระบบที่มีไฟล์หลายล้านล้านไฟล์ในหลายล้านโฟลเดอร์ดังนั้นฉันจึงไม่สามารถทดสอบได้ (ฉันเชื่อว่านับครั้งล่าสุดฉันมีประมาณ ~ 800K ไฟล์) ดังนั้นคนอื่นจะต้องลอง มัน.
ข้อแม้
แน่นอนว่าหน่วยความจำไม่ใช่ข้อ จำกัด เพียงอย่างเดียว ไดรฟ์จะเป็นคอขวดขนาดใหญ่เช่นกันเพราะสำหรับทุกไฟล์และโฟลเดอร์ที่คุณลบระบบจะต้องทำเครื่องหมายว่าว่าง โชคดีที่การใช้งานดิสก์จำนวนมากเหล่านี้จะถูกรวมเข้าด้วยกัน (แคช) และเขียนออกเป็นกลุ่มแทนที่จะเป็นรายบุคคล (อย่างน้อยสำหรับฮาร์ดไดรฟ์ไม่ใช่สำหรับสื่อที่ถอดออกได้) แต่มันจะทำให้เกิดการฟาดฟันบ้างเล็กน้อย และเขียนข้อมูล