วิธีการลบไฟล์จำนวนมากบน Windows


22

ฉันมีไดเรกทอรีที่มีล้านไดเรกทอรีย่อยและล้านล้านไฟล์ และตอนนี้ฉันต้องล้างมัน หากพูดถึงล้านล้านฉันไม่ได้พูดถึงขนาดไฟล์ แต่จำนวนไฟล์

ฉันได้ลองลบมันdel/sแล้วและใช้ Windows Explorer ไม่สามารถทำงานให้เสร็จสมบูรณ์ได้ ฉันพยายามลบไดเรกทอรีย่อยบางรายการทีละรายการและใช้เวลาหลายวัน ปัญหาที่ฉันพบคือทุกครั้งไม่ว่าจะใช้delหรือ Explorer ฉันสามารถเห็นได้ในตัวจัดการงานที่อินสแตนซ์ของ explorer ใช้หน่วยความจำสูงและค่อย ๆ ผลักระบบของฉันล้มเหลว

ยังคงมีไฟล์หลายร้อยล้านไฟล์ที่จะถูกลบ มีความเป็นไปได้ที่จะประสบความสำเร็จด้วยคำสั่ง / การกระทำหนึ่ง (หรือเพียงไม่กี่)?


[แก้ไข]

ฉันพยายามทำกับ Cygwin rm -frและให้ผลลัพธ์เดียวกัน สรุปเป็น:

  1. ไม่ว่าจะใช้ Windows Explorer DELจากพรอมต์คำสั่งหรือrmคำสั่งCygwin หน่วยความจำระบบจะค่อยๆลดลงเหลือศูนย์และในที่สุดกล่องก็จะหยุดทำงาน

  2. หาก ณ จุดใด ๆ ก่อนที่ระบบจะล้มเหลวกระบวนการจะถูกปิด (โดย CTRL + C หรือสิ่งอื่น) กล่องจะยังคงทำงานตามปกติ อย่างไรก็ตามหน่วยความจำที่ใช้ทั้งหมดจะไม่ได้รับการปลดปล่อย ว่าฉันหยุดกระบวนการในขณะที่หน่วยความจำระบบถึง 91% ที่ Task Manager บอก: รวม 4G RAM แคชคือ 329M และ 335MB ว่าง จากนั้นการใช้หน่วยความจำจะอยู่ในระดับนี้จนกว่าฉันจะรีบูตเครื่อง ถ้าฉันหยุดอินสแตนซ์ของ explorer ในตัวจัดการงานหน้าจอจะว่างเปล่าด้วยไฟ HDD ตลอดเวลาและจะไม่กลับมา โดยปกติเมื่อฉันหยุดอินสแตนซ์ explorer ในตัวจัดการงานฉันสามารถเรียกใช้อีกครั้งโดยกด Win + E หรือรีสตาร์ทโดยอัตโนมัติ

การจัดการหน่วยความจำที่ดีจริงๆ!


[แก้ไขอีกครั้ง] ดูเหมือนว่าหน่วยความจำที่ใช้แล้วบางส่วนได้รับการปลดปล่อยหลังจากใช้เวลานาน แต่ไม่ใช่ทั้งหมด หน่วยความจำแคชและที่มีอยู่บางส่วนกลับมาในตัวจัดการงาน ฉันไม่ได้รออีกต่อไปไม่แน่ใจว่าจะเกิดอะไรขึ้น


ดังนั้นปัญหาหลักของคุณคือข้อเท็จจริงที่ว่าไดเรกทอรีและไดเรกทอรีย่อยไม่ถูกลบ
Sandeep Bansal

@Jackey Cheung: คุณใช้ Windows รุ่นใดอยู่
ศิวะจรัญ

1
คุณสามารถเขียนชุดสคริปต์ที่ลบไฟล์ซ้ำ ๆ ไม่เริ่มจากระดับสูงสุด แต่เปิดเช่นระดับที่ห้าของโครงสร้างโฟลเดอร์ ที่จะแบ่งงานออกเป็น 'rm's ที่แยกต่างหากและเรียงตามลำดับ

9
ฉันต้องรู้ว่านรกคุณไม่ได้รับล้านล้านไฟล์จริงๆ ...
โมอับ

2
ล้านล้านไฟล์ต้องการตารางไฟล์ที่ 1 PB ฮาร์ดดิสก์ที่ใหญ่ที่สุดในปัจจุบันคือ TB บางตัว คุณมีพาร์ติชั่นที่ใหญ่ได้อย่างไร?
user541686

คำตอบ:


10

คำอธิบายทางเทคนิค

สาเหตุที่วิธีการส่วนใหญ่ก่อให้เกิดปัญหาคือ 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 ไฟล์) ดังนั้นคนอื่นจะต้องลอง มัน.

ข้อแม้

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


ฉันค่อนข้างแน่ใจว่ามันไม่ทำงาน ฉันลองแล้ว ปัญหาอยู่ในวงวน FOR มันเปิดออกสำหรับจะทำให้เกิดปัญหาเช่นเดียวกับการออก DEL โดยตรง
Jackey Cheung

1
ขึ้นอยู่กับสวิตช์ที่คุณใช้ หากคุณใช้/rสวิตช์แล้วตามที่ฉันอธิบายมันจะพยายามระบุไฟล์ทั้งหมด ถ้าคุณใช้/dสวิตช์มันจะระบุเฉพาะโฟลเดอร์ในไดเรกทอรีปัจจุบันเท่านั้นดังนั้นหากคุณไม่มีพันล้านโฟลเดอร์ในไดเรกทอรีปัจจุบันมันไม่ควรทำให้เกิดปัญหา
Synetech

7

ฉันไม่สามารถพูดกับไฟล์หลายล้านล้านไฟล์ได้ แต่เมื่อเร็ว ๆ นี้ฉันได้เปิดใช้งานการแชร์ไฟล์เก่าที่มีไฟล์ ~ 1.8M โดยใช้:

robocopy EmptyTMPFolder FolderToDelete /MIR /MT:16 /ETA /R:30 /W:5

"EmptyTMPFolder" เป็นไดเรกทอรีภายในเครื่องที่ว่างเปล่า ตัวเลือก / MIR จะทำให้เป้าหมายดูเหมือนแหล่งที่มา (ว่าง)

ประโยชน์ที่แท้จริงสำหรับวิธีนี้คือตัวเลือกการลองใหม่ (/ R: 30) สิ่งนี้อนุญาตให้มีโอกาสดูดซับปัญหาการเชื่อมต่อใด ๆ ที่อาจเกิดขึ้นในระหว่างกระบวนการนี้ การลบในเครื่องอาจไม่ได้ประโยชน์ในแนวทางนี้

ฉันไม่มีเกณฑ์เปรียบเทียบเฉพาะเพื่อเปรียบเทียบเวลา แต่ฉันต้องการสิ่งนี้มากกว่าตัวเลือกอื่น ๆ ที่แนะนำ b / c ของตัวเลือกการลอง / รอ การลบเริ่มใกล้ทันที


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

5

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

ตัวเลือกอื่นอาจใช้ลินุกซ์ distro บางตัวในไลฟ์ซีดีที่สามารถอ่านได้จากพาร์ติชัน NTFS ฉันรู้จากประสบการณ์ส่วนตัวที่rm -rf folderNameสามารถทำงานได้อย่างน้อย 2 วันโดยไม่ต้องขัดข้องกับระบบที่มี RAM 2GB จะใช้เวลาสักครู่ แต่อย่างน้อยก็จะเสร็จสิ้น


1
hm, Linux ฉันกำลังคิดเกี่ยวกับ Cygwin ถึงแม้ว่ามันควรจะใช้ฟังก์ชั่นขีดเส้นใต้ของ Windows เพียงแค่สงสัยว่ามันจะสร้างความแตกต่างในกรณีใด ฉันจะลองดู
Jackey Cheung

1
คุณสามารถใช้ git bash
rain

4

เอ่อ .. ฉันไม่อยากรู้ว่าคุณสร้างมามากแค่ไหน

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

คุณลองคำสั่งแล้วrmdir /sหรือยัง ตราบใดที่มันลบไฟล์ตามที่พวกเขาพบแทนที่จะรอให้ทุก ๆ ไฟล์ระบุมันอาจใช้งานได้

มีไดเรกทอรีย่อยกี่ระดับ หากมีเพียงหนึ่งหรือจำนวนต่ำอื่น ๆ ไฟล์แบตช์ด่วนที่ recurses ด้วยตนเองอาจทำงานได้

วิธีใดก็ตามจะใช้เวลาสักครู่


นอกเหนือจากคำแนะนำของฟอร์แมต Soandos แล้วแน่นอน มันจะเร็ว แต่ถ้านี่เป็นไดรฟ์ระบบของคุณคุณจะต้องติดตั้ง Windows ใหม่
บ๊อบ

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

@soandos Explorer นับทุกไฟล์ ฉันคิดว่าวิธีการบางอย่างที่ใช้รูปแบบการแจงนับ DFS: ไปให้ไกลที่สุดเท่าที่จะทำได้ลงสาขาลบเมื่อมันฮิตไฟล์ก่อนที่จะกลับมาขึ้น ในคำอื่น ๆ เรียกซ้ำซึ่งเป็นสิ่งที่rm -rfไม่ ซึ่งทำงานได้ดีที่สุดกับโครงสร้างไดเรกทอรีที่ค่อนข้างตื้น ฉันไม่แน่ใจว่าrmdir /sทำสิ่งนี้หรือไม่ มันควรจะเป็น
บ๊อบ

1
@JackeyCheung rmdir /?: /s Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree.กล่าวอีกนัยหนึ่งการ/sตั้งค่าสถานะจะลบไฟล์ด้วย คุณใช้งานdelอย่างไร และใช่มันอาจจะดีกว่าถ้าใช้rm -rfตามที่แนะนำไว้
บ๊อบ

1
@ JackeyCheung: คุณผิด หากคุณให้ค่าสถานะ rmdir / s มันจะลบไฟล์เช่นเดียวกับไดเรกทอรี
Harry Johnston

4

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

fsutil behavior set DisableDeleteNotify 1

โปรดทราบว่าการเปลี่ยนแปลงนี้อาจส่งผลกระทบต่อประสิทธิภาพการทำงานของไดรฟ์โซลิดสเตตและอาจป้องกันอัตโนมัติและ / หรือการทำให้เป็นปกติของไดรฟ์ SAN


3

Shift+ Deleteข้ามถังรีไซเคิลและอาจเร่งความเร็วของสิ่งต่าง ๆ อย่างมีนัยสำคัญ

หากไม่ได้ผล (กรณีร้ายแรง) ให้ลองใช้ยางลบโฟลเดอร์อย่างรวดเร็วและ / หรือยางลบไดเรกทอรีจำนวนมาก


เมื่อฉันพยายามที่จะลบไฟล์รูปภาพจำนวนมากใช่ Shift Shift นั้นค่อนข้างเร็วถ้าเทียบกับ DEL ปกติขอบคุณ
V-SHY

3

อาจเป็นเพราะแอนติไวรัส / มัลแวร์ของคุณใช้หน่วยความจำทั้งหมดแล้วหยุดระบบ

Windows เองไม่มีปัญหาในการลบไฟล์จำนวนมากถึงแม้ว่ามันจะช้ากว่าการทำงานที่คล้ายกันในระบบไฟล์ที่ไม่ใช่ของ Microsoft ส่วนใหญ่


จุดดี! ดูคุ้มค่าแน่นอน
Jackey Cheung

ฉันปิดโปรแกรมป้องกันไวรัสและหน่วยความจำยังคงกินเหมือนเมื่อก่อน
Jackey Cheung

การปิดโปรแกรมป้องกันไวรัสไม่ได้ช่วยเพิ่มหน่วยความจำหลังจากกระบวนการหยุดทำงานเช่นกัน
Jackey Cheung

@JackeyCheung: โปรแกรมป้องกันไวรัสคืออะไร บางคนไม่ได้จริงปิดอย่างสมบูรณ์ ...
เบนยต์

2

ปัญหาที่คุณอาจพบคือไดเรกทอรีไม่ได้รับการกระชับเมื่อคุณลบไฟล์ / โฟลเดอร์ดังนั้นหากคุณมีโฟลเดอร์ที่มีไฟล์อยู่ 1 ล้านไฟล์และลบ 500k แรกของพวกเขา มีบล็อกจำนวนมากที่จุดเริ่มต้นของไดเรกทอรีของคุณซึ่งมีไว้สำหรับช่องว่างทั้งหมด

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

อีกสิ่งที่คุณอาจลองใช้คือเครื่องมือของบุคคลที่สามเช่น "PerfectDisk" ไปยังโฟลเดอร์ Compact หลังจากลบไฟล์จำนวนมาก


2

ลองใช้วิธีการต่าง ๆ เพื่อลบไฟล์บันทึกฟิวชั่นมากกว่า 10 ล้านไฟล์ฉันสังเกตว่าไฟล์เฉลี่ยประมาณ 30K นั้นสามารถลบได้ในระยะเวลา 10 นาที อาจใช้เวลาประมาณ 55 ชั่วโมงสำหรับไฟล์ 10 ล้านไฟล์ ...

เมื่อใช้สคริปต์ด้านล่างอัตราการลบจะเพิ่มขึ้น ~ 75% รายชื่อไฟล์ถูกสร้างและดำเนินการโดยกระบวนการที่เกิดขึ้นพร้อมกันซึ่งเพิ่มการทำงานของดิสก์ (แต่ไม่เชิงเส้น) ฉันกำลังแสดงส้อม 4 อัน แต่สองอันอาจพอเพียง

มีตัวเลือกในการใช้ PowerShell ซึ่งจะช่วยลดเวลาที่จำเป็นในการจัดทำรายการเป็นอย่างมาก

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

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF /I "%~1"=="timestamp" (
    CALL :ECHOTIMESTAMP
    GOTO END
)

rem directory structure to delete
SET "DELETE=c:\_delete\Content.IE5\???<<<change this>>>???"
rem primary list of discovered files to delete
SET "LIST=delete-list.txt"
rem base path for sub-lists
SET "LISTBASE=.\delete-list"
SET "TITLE=Batch Delete Process"
rem specifies number of batch delete processes to spawn
SET FORKS=4
rem when set to 1, use PowerShell for list building and delete.  Definitely improves time to build fork sublists
SET POWERSHELL=0
rem specifies max files to delete when greater than 0
SET MAXDEL=1000000

rem prompt for confirmatoin
SET /P CONT=About to delete all files and directories from !DELETE!. Continue (Y/N)?
IF /I NOT "!CONT!"=="Y" EXIT /B

CALL :ECHOTIMESTAMP

ECHO Accumulating list of files to delete...
dir /b /s "!DELETE!" > "!LIST!"

FOR /F "delims=" %%c IN ('type "!LIST!" ^| find /C ":"') DO SET "COUNT=%%c"
ECHO Discoverd !COUNT! files and directories to delete.

IF  %MAXDEL% GTR 0 IF !COUNT! GTR %MAXDEL% (
    SET COUNT=%MAXDEL%
    ECHO Limiting files/directories deletion count to  !COUNT!
)

CALL :ECHOTIMESTAMP
ECHO Preparing !FORKS! delete processes...
SET /A LIMIT=!COUNT!/!FORKS!

IF !POWERSHELL! EQU 1 (
    SET SKIP=0
    FOR /L %%n IN (1,1,!FORKS!) DO (
        SET "CURRENT=!LISTBASE!-%%n.txt"
        SET "LIST[%%n]=!CURRENT!"
        DEL /f /q "!CURRENT!" > nul 2>&1
        IF %%n EQU !FORKS! SET /A LIMIT+=!FORKS!
        SET CMD=type \"!LIST!\" ^| select -first !LIMIT! -skip !SKIP!
        powershell -command "& {!CMD!}" > "!CURRENT!"
        SET /A SKIP+=!LIMIT!
    )

) ELSE (
    rem significantly slower but no PowerShell.
    SET L=1
    SET N=!LIMIT!
    SET C=0
    FOR /F %%f  IN (!LIST!) DO (
        IF !C! LSS !COUNT! (
            IF !N! GEQ !LIMIT! (
                SET "CURRENT=!LISTBASE!-!L!.txt"
                SET "LIST[!L!]=!CURRENT!"
                DEL /f /q "!CURRENT!" > nul 2>&1
                SET /A L+=1
                SET /A N=0
            ) ELSE (
                SET /A N+=1
            )
            ECHO %%f >> "!CURRENT!"
        ) ELSE (
            GOTO ENDLIST
        )
        SET /A C+=1
    )
)
:ENDLIST

CALL :ECHOTIMESTAMP
ECHO Forking !FORKS! delete processes...
FOR /L %%t IN (1,1,!FORKS!) DO (

    SET "CURRENT=!LIST[%%t]!"
    IF !POWERSHELL! EQU 1 (
        SET "TAB=        "
        SET BLANK=!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!
        SET BLANK=!BLANK!!BLANK!!BLANK!!BLANK!
        SET DEL_CMD=del -force -recurse -ea SilentlyContinue -path \"$_\"
        SET $W_CMD=$w=$Host.UI.RawUI.WindowSize.Width
        SET $S_CMD=$s=\"$_\";$i=[math]::max^(0,$s.length-$w^);$s=$s.substring^($i, $s.length-$i^);$s=\"$s !BLANK!\";$s=$s.substring^(0,[math]::min($w,$s.length^)^)
        SET ECHO_CMD=Write-Host \"`r$s\" -NoNewLine
        SET CMD=type \"!CURRENT!\" ^| %% {!DEL_CMD!; !$W_CMD!; !$S_CMD!; !ECHO_CMD!}
        SET CMD=powershell -command "^& {!CMD!}" ^& ECHO\ ^& "%~dpnx0" timestamp
        ECHO CMD !CMD!
    ) ELSE (
        SET LOOP=FOR /F %%%f IN ^(!CURRENT!^) DO
        SET OP=del "%%%f"
        SET CMD=@ECHO OFF ^&^& ^(!LOOP! !OP!  ^> nul 2^>^&1 ^)  ^& "%~dpnx0" timestamp
    )
    rem ECHO !CMD!
    START "!TITLE! %%t" cmd /k  !CMD!
)

GOTO END

:ECHOTIMESTAMP
SETLOCAL
    SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
    SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
    ECHO !DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL
GOTO :EOF

:END
ENDLOCAL
EXIT /B

2

ลองสิ่งนี้และแก้ไขตามที่คุณต้องการ ..

มันเป็นสคริปต์ทดสอบบน Win2003 ตามคำอธิบายและการวิเคราะห์ทางเทคนิคของ Synetech ตอบ 15 ตุลาคม '13 เวลา 15:22

@echo off

rem ### USE FULL PATH AS FIRST ARGUMENT TO SCRIPT, DONT FORGET QUOTES !
rem ### If you move this script, fix script path variable...
SET STATICFULLSCRIPTPATH="D:\scripts\FOLDER"
SET SCRIPTNAME="DeleteFast.bat"

rem ### If CD fails or IF condition has problems,
rem ### and DEL or RMDIR runs, its better to be at safe place.
if not exist "%TEMP%\SAFE" mkdir "%TEMP%\SAFE"
if exist "%TEMP%\SAFE" cd /d "%TEMP%\SAFE"

rem ### Fix quote overflow
set var1="%1"
set var1=%var1:"=%

if not [%1]==[] (
    cd /d "%var1%"

    echo # KILLING F AT : "%var1%"
    rem ### uncomment to do damage! ### 
    rem # del /f/q * > nul

    for /d %%i in (*) do call "%STATICFULLSCRIPTPATH%\%SCRIPTNAME%" "%var1%\%%i"

    rem ## Finish deleting the last dir
    cd /d "%var1%\.."

echo # KILLING  DIR : "%var1%"
rem ## Remove dir.. first try
rmdir /q "%var1%"

if exist "%var1%" (
    rem ## Remove dir.. second try
    rem ## If thousands of files/dirs had permission/ownership problems, then prepare to wait a long time.
    rem ### uncomment to do damage! ### 
    rem #cmd.exe /c takeown /f "%var1%" && icacls "%var1%" /grant SOMEBODY:F

    rem ### uncomment to do damage! ### 
    rem #rmdir /s/q "%var1%"
)
)

cd /d "%STATICFULLSCRIPTPATH%"

Testrun .. มีโฟลเดอร์เช่น A1 ถึง A4, B1 ถึง B4 และ C1 ถึง C4 ซ้อนกันต่างกัน ..

Z:\>"D:\scripts\FOLDER\DeleteFast.bat" "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS"

D:\scripts\FOLDER>

ฉันไม่สามารถแสดงความคิดเห็น (เว็บไซต์บ่นเกี่ยวกับชื่อเสียงของฉัน) ดังนั้นฉันจึงเพิ่มความคิดเห็นของฉันที่นี่ ..

วิธีการแก้ปัญหาของ Bjv สร้างผู้สร้างไฟล์ชั่วคราวที่ไร้ประโยชน์ แล้วย้ำอีกครั้งเพื่อทำงานจริง /superuser//a/892412/528695

สคริปต์ต้นฉบับของ Synetech ไม่ได้ผลสำหรับฉัน /superuser//a/416469/528695

@echo off
if not [%1]==[] cd /d %1
echo "%1"
for /d %%i in (*) do call %0 "%%i"

ผล..

Z:\>C:\privscripts\TESTF\DeleteFastORIGINAL.bat "C:\privscripts\TESTF\DIRS"
""C:\privscripts\TESTF\DIRS""
""A1""
""B1""
""C1""
The system cannot find the path specified.
""B2""
The system cannot find the path specified.
""A2""
The system cannot find the path specified.
""A3""
The system cannot find the path specified.
""A4""

C:\privscripts\TESTF\DIRS\A1\B1\C1>

ฉันสามารถตรวจสอบได้ว่า @ user4350129 ถูกต้องเมื่อเขาบอกว่าสคริปต์ของ Synetech ไม่ทำงาน - ฉันมีพฤติกรรมแบบเดียวกันในกล่อง Win7x64 ของฉัน
leinad13

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

2

ฉันมีปัญหาที่คล้ายกันเมื่อเวลาผ่านมามีเพียง 10 ล้านไฟล์ แต่ในเซิร์ฟเวอร์ 2003 เพื่อลบไฟล์ที่ฉันใช้เซิร์ฟเวอร์ ftp / ไคลเอนต์และลูกค้าออกจากการลบไฟล์และโฟลเดอร์ มันเป็นทางออกที่ช้า แต่ทำงานได้สมบูรณ์

อาจเป็นไปได้ว่าคุณจะมีปัญหาที่สองกับ MFT ใน NTFS ที่ไม่มีวิธีแก้ปัญหา MFT เป็นอาร์เรย์ที่ชนะในปี 2003 (ฉันไม่แน่ใจว่า Microsoft มีทางออกหลังจากที่ชนะ 2003) จะเก็บไฟล์ทั้งหมดด้วยวิธีที่เพิ่มขึ้นดังนั้น ด้วยขนาดไฟล์นับล้านล้านขนาดจะเป็นบ้าในกรณีของฉัน MFT มี 17 ล้านเรคคอร์ดและขนาดของ MFT อยู่ที่ประมาณ 19GB ด้วยไฟล์เพียง 45000 ไฟล์ฉันทดสอบในระบบอื่นและดูเหมือนว่าจะมี 1 ล้านเรคคอร์ดที่ MFT จะ ประมาณ 1 GB

คุณสามารถตรวจสอบสถานะของ MFT ด้วยคำสั่งนี้:

defrag C: /a /v
  • C: - ตัวอักษรหน่วย
  • /a - วิเคราะห์
  • /v - verbose

อีกวิธีที่ยุ่งยากเนื่องจากไม่มีเครื่องมือที่สามารถย่อขนาด MFT ได้เครื่องมือเพียงแค่กรอกชื่อของไฟล์และคุณสมบัติ แต่ไม่มีอะไรมากกว่า 0 แต่คุณสามารถใช้ตัวแปลง VMware หรือ P2V ชนิดอื่นและสร้างเครื่องเสมือนขึ้นอยู่กับ เซิร์ฟเวอร์ของคุณในแบบที่คุณจะแก้ไขปัญหาทั้งหมดที่เกี่ยวข้องกับ MFT ฉันไม่เคยทดสอบการแปลงจาก V2P ตอนนี้ฉันทำงานเฉพาะในสภาพแวดล้อมเสมือน แต่ฉันเห็นข้อมูลมากมายเกี่ยวกับมันบนอินเทอร์เน็ต

ที่ชนะ 2003 มันทำงานได้อย่างสมบูรณ์แบบในขณะนี้ขนาดของ MFT คือ 40MB และทุกอย่างก็โอเคถ้าคุณต้องการฉันสามารถบอกคุณเพิ่มเติมเกี่ยวกับการสำรองข้อมูล, defrags หรืองานอื่น ๆ ที่เกี่ยวข้องกับไฟล์เล็ก ๆ นับล้าน


1

ต่อคำตอบนี้ใน StackOverflowใช้การรวมกันของdelและrmdir:

del /f/s/q foldername > nul
rmdir /s/q foldername

ใช่ฉันเคยอ่านเรื่องนี้มาก่อน จริงๆแล้วมันไม่ได้ช่วยในกรณีของฉัน เนื่องจากคำสั่ง del เกิดปัญหาขึ้นอย่างแน่นอน
Jackey Cheung

1

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

 find dir \! -type d | sed 's/^/rm /' | sh

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

ตอนนี้คุณไม่มีอะไรเหลือนอกจากไดเรกทอรี นี่คือสิ่งที่ได้รับเย็น บางทีคุณอาจลบไฟล์เพียงพอเพื่อให้คุณสามารถทำได้rm -rfโดยไม่ใช้หน่วยความจำไม่เพียงพอ(และอาจจะเร็วกว่าสคริปต์อื่น) ถ้าไม่เราสามารถปรับคำตอบ Stackoverflowนี้:

 find dir | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2 | sed 's/^/rmdir /' | sh

อีกครั้งอาจจำเป็นต้องปรับแต่งคราวนี้ด้วยsortเพื่อหลีกเลี่ยงการสร้างไฟล์ชั่วคราวขนาดใหญ่


1

ฉันพบปัญหาเดียวกันเมื่อไม่นานมานี้ ฉันเขียนโปรแกรมอรรถประโยชน์ขนาดเล็กที่ทำสิ่งนั้นอย่างแน่นอน: ลบไดเรกทอรีซ้ำ มันจะไม่แจกแจงไฟล์และมันจะไม่ใช้หน่วยความจำมาก (O (n + m) ที่สูงสุดด้วย n = ความลึกไดเรกทอรีสูงสุดและ m = จำนวนไฟล์ / ไดเรกทอรีสูงสุดในหนึ่งในส่วนย่อย) มันสามารถจัดการ filepaths ยาว (> 256 ตัวอักษร) ฉันชอบที่จะได้รับข้อเสนอแนะถ้าคุณสามารถแก้ปัญหาของคุณด้วยสิ่งนี้

คุณสามารถค้นหาได้ที่นี่: https://github.com/McNetic/fdeltree (ปฏิบัติการในโฟลเดอร์ release)


1

ฉันพบเธรดนี้กำลังมองหาวิธีที่ดีกว่าที่ฉันมีในการลบไฟล์มากกว่า 3 ล้านไฟล์ในเซิร์ฟเวอร์หลายตัวที่ฉันสนับสนุน ด้านบนเป็นวิธีที่ซับซ้อนกว่า IMO ดังนั้นฉันจึงใช้วิธีที่รู้จักกันในการใช้เครื่องมือบรรทัดคำสั่ง "FORFILES" ใน Windows (นี่คือใน Server 2003)

อย่างไรก็ตามด้านล่างนี้เป็นคำสั่ง FORFILES ที่ฉันใช้เพื่อลบไฟล์ทั้งหมดในโฟลเดอร์จากบรรทัดคำสั่ง

forfiles / P "เส้นทางโฟลเดอร์ของคุณที่นี่ (เช่น C: \ Windows \ Temp)" / C "cmd / c echo @file & del / f / q @file"

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

ใช้เวลาสักครู่ในการเริ่มต้นเช่นดูเหมือนว่ามันไม่ได้ทำอะไรสักอย่าง (ประมาณ 30m สำหรับไฟล์ ~ 3 ล้านล้านไฟล์) แต่ในที่สุดคุณควรเห็นชื่อไฟล์เริ่มปรากฏเมื่อลบออก วิธีนี้ยังใช้เวลานานในการลบไฟล์ (เวลาในการลบอาจลดลงหากไม่มีเสียงก้อง) แต่ในที่สุดมันจะทำงานโดยไม่ล้มเหลวบนเครื่องเซิร์ฟเวอร์ของฉัน forfiles ใช้หน่วยความจำ ~ 1,850Kb ในระหว่างกระบวนการลบ .. .

ระยะเวลาสำหรับการลบอาจทำให้เกิดปัญหาหากเซิร์ฟเวอร์ของคุณมีการออกจากระบบอัตโนมัติตามที่คุณต้องการเพื่อให้เมาส์เคลื่อนที่ (ฉันขอแนะนำให้ทำงานในฐานะผู้ใช้ Console หรือผ่านเครื่องมือส่วนที่ 3 เช่น LanDesk หรือ SCCM เป็นต้น) หรือ MouseJiggle exe))

อย่างไรก็ตามคิดว่าฉันจะแบ่งปันคำตอบของฉันโชคดีทั้งหมด!

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