RemoveDirectory(); Chỉ xóa thư mục trống, nhưng làm thế nào để loại bỏ các thư mục có tập tin bên trong?Làm thế nào để loại bỏ thư mục đệ quy?
Trả lời
Nếu bạn đã sẵn sàng sử dụng API Windows thì cách dễ nhất để thực hiện việc này là gọi SHFileOperation
. Sử dụng thao tác FO_DELETE
và đừng quên để tăng gấp đôi null-chấm dứt tên thư mục của bạn.
Hãy nhớ rằng SHFileOperation hoạt động tốt cho các ứng dụng Chế độ người dùng nhưng không hoạt động khi được gọi từ Dịch vụ Windows, đặc biệt nếu Mạo danh đang được sử dụng để xóa thư mục trên mạng chia sẻ UNC. Đối với kịch bản này, bạn sẽ cần phải làm công việc grunt và sử dụng FindFirstFile()/FindNext() với DeleteFile()/RemoveDirectory() cách cứng – WebDrive
Thông thường, nếu không có phương thức thư viện nào, điều này được thực hiện bằng cách đệ quy. Một hàm lặp lại tất cả các mục nhập thư mục, xóa các tệp 'bình thường' và tự gọi nó bằng bất kỳ đường dẫn thư mục nào được tìm thấy. Điều này phá hủy toàn bộ cây thư mục, (phiên bản Windows của tôi đã kiểm tra rõ ràng trên đường dẫn được thông qua để ngăn chặn nó phá hủy các thư mục hệ điều hành trong trường hợp vô tình đi qua trong một tham số tự tử).
Đây có thể là khập khiễng, nhưng hãy cân nhắc sử dụng
system("rd /s /q ...");
Nó xấu xí, nhưng nó quá đơn giản để bỏ qua. Nó cũng có tất cả các "làm thế nào để đối phó với các tập tin trên mạng chia sẻ" công cụ làm việc ra ngoài. Bất kỳ giải pháp nào bạn đưa ra có thể là việc thực hiện lại (không đầy đủ và/hoặc không chính xác) của rd
, vì vậy, hãy gọi ra quy trình bên ngoài thực sự sẽ là sử dụng lại mã tốt đẹp. ;-)
Tái sử dụng mã và không thể xuất hiện với thậm chí không biên dịch lỗi nếu rd không tồn tại . Đối với một chương trình rất nhỏ, điều này có thể hữu ích và đúng, đối với những người lớn tuổi thọ lớn, ít hơn. Cá nhân, tôi sẽ luôn kiểm tra xem lệnh đó có tồn tại không. –
@phresnel: Câu hỏi chỉ dành cho các hệ thống Windows, và 'rd' có sẵn trên tất cả các hệ thống Windows theo mặc định. Tôi muốn đi ra ngoài một chi và tuyên bố rằng 'thứ' đang có sẵn có nhiều khả năng hơn 'SHFileOperation' đang có sẵn (' SHFileOperation' chỉ tồn tại từ Windows XP, và nó đã không được chấp nhận với Windows Vista). –
Xác suất ít liên quan đến tôi. Cá nhân, tôi không phải là một lỗi thời gian biên dịch nếu một số chức năng không có; với hệ thống bạn chưa bao giờ có lỗi biên dịch thời gian. Như đã nói, đối với các chương trình nhỏ, hệ thống cụ thể, điều này có thể không sao. Nhưng tôi sẽ tư vấn chống lại nó cho các chương trình lớn hơn hoặc sống lâu. Bạn không bao giờ biết những gì trong 5, 10, 15 năm kể từ bây giờ. Nếu đột nhiên mọi người sẽ chuyển sang Mac hoặc Linux, thì chắc chắn bạn cũng sẽ muốn con bò tiền mặt của bạn chạy trên nền tảng đó. –
Giải pháp tốt nhất, nếu bạn có thể sử dụng, là boost::filesystem::remove_all
. Bằng cách đó, bạn không phải lo lắng về nền tảng cụ thể. Tôi không biết về bất kỳ giải pháp độc lập nền tảng nào khác; cách thông thường khác sẽ liên quan đến việc đọc thư mục, và đệ quy giảm dần nó (nhưng cách đọc thư mục cũng sử dụng boost::filesystem
hoặc mã phụ thuộc hệ thống).
Theo MSDN, SHFileOperation không phải là luồng an toàn khi được sử dụng với đường dẫn tương đối. Nó chỉ có thể được sử dụng một cách an toàn với đường dẫn tuyệt đối.
tôi khuyên bạn nên sử dụng mã này để thay thế:
double directory_delete(char *pathname)
{
string str(pathname);
if (!str.empty())
{
while (*str.rbegin() == '\\' || *str.rbegin() == '/')
{
str.erase(str.size()-1);
}
}
replace(str.begin(),str.end(),'/','\\');
struct stat sb;
if (stat((char *)str.c_str(),&sb) == 0 &&
S_ISDIR(sb.st_mode))
{
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
TCHAR DirPath[MAX_PATH];
TCHAR FileName[MAX_PATH];
_tcscpy(DirPath,(char *)str.c_str());
_tcscat(DirPath,"\\*");
_tcscpy(FileName,(char *)str.c_str());
_tcscat(FileName,"\\");
hFind = FindFirstFile(DirPath,&FindFileData);
if (hFind == INVALID_HANDLE_VALUE) return 0;
_tcscpy(DirPath,FileName);
bool bSearch = true;
while (bSearch)
{
if (FindNextFile(hFind,&FindFileData))
{
if (!(_tcscmp(FindFileData.cFileName,".") &&
_tcscmp(FindFileData.cFileName,".."))) continue;
_tcscat(FileName,FindFileData.cFileName);
if ((FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY))
{
if (!directory_delete(FileName))
{
FindClose(hFind);
return 0;
}
RemoveDirectory(FileName);
_tcscpy(FileName,DirPath);
}
else
{
if (FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_READONLY)
_chmod(FileName, _S_IWRITE);
if (!DeleteFile(FileName))
{
FindClose(hFind);
return 0;
}
_tcscpy(FileName,DirPath);
}
}
else
{
if (GetLastError() == ERROR_NO_MORE_FILES)
bSearch = false;
else
{
FindClose(hFind);
return 0;
}
}
}
FindClose(hFind);
return (double)(RemoveDirectory((char *)str.c_str()) == true);
}
else
{
return 0;
}
}
Nếu bạn muốn sử dụng mã của tôi "như-là", bạn sẽ cần những tiêu đề và như vậy ở phía trên cùng của tập tin cpp của bạn:
#include <windows.h> // winapi
#include <sys/stat.h> // stat
#include <tchar.h> // _tcscpy,_tcscat,_tcscmp
#include <string> // string
#include <algorithm> // replace
using namespace std;
... và tôi nghĩ vậy.
Mã của tôi được dựa trên bài viết này:
tôi khuyên các bạn không bao giờ sử dụng SHFileOperation, ngoài vấn đề an toàn, nó được thay thế bởi IFileOperation kể từ Windows Vista.
Hy vọng điều này sẽ hữu ích!
- 1. PHP - Làm thế nào để loại bỏ các mục rỗng của một mảng đệ quy?
- 2. Làm thế nào để tôi đệ quy loại bỏ thư mục từ lanh lợi hệ thống theo dõi
- 3. Làm thế nào để loại bỏ nhiều thư mục ảo?
- 4. Đệ quy tạo thư mục
- 5. Loại bỏ đệ quy đuôi là gì?
- 6. CMD: Làm cách nào để đệ quy xóa thuộc tính "Ẩn" của tệp và thư mục
- 7. PHP đường dẫn thư mục đệ quy
- 8. Thư mục đệ quy Python đọc
- 9. Làm thế nào để đệ quy các thư mục đi qua trong C trên Windows
- 10. Làm thế nào để loại trừ một thư mục trong một tìm kiếm đệ quy bằng grep?
- 11. SVN - làm thế nào để loại bỏ một thư mục bin gây ra các thư mục src được loại bỏ để thay thế?
- 12. Làm thế nào tôi có thể đệ quy đọc các thư mục trong Perl?
- 13. Diff Một thư mục đệ quy, bỏ qua tất cả các tập tin nhị phân:
- 14. Từng bước loại bỏ đệ quy gián tiếp này
- 15. Loại chung đệ quy
- 16. Mẫu đầu bếp có các thư mục đệ quy
- 17. Tải xuống thư mục đệ quy với Paramiko?
- 18. Ruby: làm cách nào để đệ quy tìm và xóa thư mục trống?
- 19. Làm cách nào để tìm tập tin đệ quy trong các thư mục
- 20. Làm thế nào để loại bỏ lỗi sâu đệ quy tối đa trong khi vẽ đồ thị tương tác?
- 21. Đệ quy đổi tên thư mục trong bash
- 22. Làm thế nào để loại bỏ các nội dung trong thư mục Cache?
- 23. làm thế nào để loại bỏ tên thư mục từ url bằng htaccess
- 24. Làm thế nào để đệ quy đi qua tất cả các thư mục con và đọc tệp?
- 25. Thực hiện đệ quy trong các thư mục con
- 26. Làm thế nào để lọc tệp khi sử dụng scp để sao chép thư mục đệ quy?
- 27. Trình lặp lại thư mục PHP đệ quy - bỏ qua một số tệp nhất định.
- 28. Linux đệ quy chmod chỉ trên các thư mục con
- 29. Có CMake đệ quy quét các thư mục không?
- 30. Thư mục Zip đệ quy, lưu cho một thư mục con đã cho (Linux)
Trên nền tảng nào? –
@OliCharlesworth sir, trên windows xp –
Bạn đã thử gì? – Nawaz