Giải thích kỹ thuật
Lý do mà hầu hết các phương pháp đang gây ra vấn đề là Windows cố gắng liệt kê các tệp và thư mục. Đây không phải là vấn đề với vài trăm tập tin hoặc thậm chí hàng nghìn tập tin sâu ở một vài cấp độ sâu, nhưng khi bạn có hàng nghìn tỷ tập tin trong hàng triệu thư mục đi sâu hàng chục cấp, thì điều đó chắc chắn sẽ làm hỏng hệ thống .
Giả sử bạn chỉ có 100.000.000 tập tin và Windows sử dụng một cấu trúc đơn giản như thế này để lưu trữ từng tệp cùng với đường dẫn của nó (theo cách đó bạn tránh lưu trữ từng thư mục riêng biệt, do đó tiết kiệm được một số chi phí):
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
}
Tùy thuộc vào việc nó sử dụng các ký tự 8 bit hay ký tự Unicode (nó sử dụng Unicode) và hệ thống của bạn là 32 bit hay 64 bit, thì nó sẽ cần từ 25 GB đến 49 GB bộ nhớ để lưu danh sách (và đây là một cấu trúc đơn giản hóa).
Lý do tại sao Windows cố gắng liệt kê các tệp và thư mục trước khi xóa chúng khác nhau tùy thuộc vào phương pháp bạn đang sử dụng để xóa chúng, nhưng cả Explorer và trình thông dịch lệnh đều làm điều đó (bạn có thể thấy độ trễ khi bạn khởi tạo lệnh). Bạn cũng có thể thấy đèn flash hoạt động của đĩa (HDD LED) khi nó đọc cây thư mục từ ổ đĩa.
Giải pháp
Đặt cược tốt nhất của bạn để đối phó với loại tình huống này là sử dụng một công cụ xóa để xóa từng tệp và thư mục một lần. Tôi không biết nếu có bất kỳ công cụ làm sẵn để làm điều đó, nhưng nó nên có thể thực hiện với một lô-file đơn giản.
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
Điều này làm là để kiểm tra nếu một đối số đã được thông qua. Nếu vậy, nó sẽ thay đổi thư mục được chỉ định (bạn có thể chạy nó mà không cần đối số để bắt đầu trong thư mục hiện tại hoặc chỉ định một thư mục, ngay cả trên một ổ đĩa khác để bắt đầu ở đó).
Tiếp theo, nó xóa tất cả các tập tin trong thư mục hiện tại. Trong chế độ này, nó không nên liệt kê bất cứ thứ gì và chỉ cần xóa các tệp mà không chiếm nhiều bộ nhớ, nếu có ,.
Sau đó, nó liệt kê các thư mục trong thư mục hiện tại và tự gọi nó, chuyển từng thư mục cho nó (tự) để lặp lại xuống dưới.
Phân tích
Lý do mà điều này nên hoạt động là vì nó không liệt kê từng tệp và thư mục trong toàn bộ cây . Nó không liệt kê bất kỳ tập tin nào cả, và chỉ liệt kê các thư mục trong thư mục hiện tại (cộng với các thư mục còn lại trong thư mục mẹ). Giả sử chỉ có vài trăm thư mục con trong bất kỳ thư mục đã cho nào, thì điều này không quá tệ và chắc chắn cần ít bộ nhớ hơn các phương thức khác liệt kê toàn bộ cây.
Bạn có thể tự hỏi về việc sử dụng công /r
tắc thay vì sử dụng đệ quy (thủ công). Điều đó sẽ không hoạt động bởi vì trong khi /r
chuyển đổi không đệ quy, nó liệt kê trước toàn bộ cây thư mục chính xác là những gì chúng ta muốn tránh; chúng tôi muốn xóa khi chúng tôi đi mà không theo dõi.
So sánh
Hãy so sánh phương pháp này với (các) phương pháp liệt kê đầy đủ.
Bạn đã nói rằng bạn đã có hàng triệu thư mục. Hãy nói 100 triệu. Nếu cây gần như cân bằng và giả sử trung bình khoảng 100 thư mục con trên mỗi thư mục, thì thư mục lồng nhau sâu nhất sẽ có khoảng bốn cấp xuống trên thực tế, sẽ có 101.010.100 thư mục con trong toàn bộ cây. (Giải thích làm thế nào 100M có thể phá vỡ chỉ còn 100 và 4.)
Vì chúng tôi không liệt kê các tệp, chúng tôi chỉ cần theo dõi tối đa 100 tên thư mục cho mỗi cấp độ, cho tối đa các 4 × 100 = 400
thư mục tại bất kỳ thời điểm nào.
Do đó, yêu cầu bộ nhớ phải là ~ 206,25KB, trong giới hạn của bất kỳ hệ thống hiện đại (hoặc mặt nào khác).
Kiểm tra
Thật không may (?) Tôi không có một hệ thống với hàng nghìn tỷ tệp trong hàng triệu thư mục, vì vậy tôi không thể kiểm tra được (tôi tin ở lần đếm cuối cùng, tôi có khoảng ~ 800 nghìn tệp), vì vậy người khác sẽ phải thử nó
Hãy cẩn thận
Tất nhiên bộ nhớ không phải là giới hạn duy nhất. Ổ đĩa cũng sẽ là một nút cổ chai lớn bởi vì đối với mỗi tệp và thư mục bạn xóa, hệ thống phải đánh dấu nó là miễn phí. Rất may, nhiều thao tác trên đĩa này sẽ được gói lại với nhau (được lưu trong bộ nhớ cache) và được viết ra thành từng khối thay vì riêng lẻ (ít nhất là cho các ổ đĩa cứng, không phải cho phương tiện lưu động), nhưng nó vẫn sẽ gây ra một chút lỗi khi hệ thống đọc và ghi dữ liệu.