C 또는 C++에서 비어 있지 않은 디렉토리를 프로그래밍 방식으로 제거
C 또는 C++에서 비어 있지 않은 디렉토리를 삭제하려면 어떻게 해야 합니까?어떤 기능이 있나요?rmdir는 빈 디렉토리만 삭제합니다.외부 라이브러리를 사용하지 않는 방법을 제공해 주세요.
C 또는 C++에서 파일을 삭제하는 방법도 알려주세요.
POSIX 준거 OS 를 사용하고 있는 경우는, 파일 트리 트래버설 및 삭제(파일 또는 디렉토리 삭제)에 사용할 수 있습니다.C++에 있고 프로젝트에서 부스트를 사용하는 경우 부스트를 사용하는 것도 나쁘지 않습니다.Manuel이 제안한 파일 시스템.
다음 코드 예에서는 심볼릭링크와 마운트포인트를 통과하지 않기로 결정했습니다(대략적인 삭제를 피하기 위해서만).
#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>
static int rmFiles(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
{
if(remove(pathname) < 0)
{
perror("ERROR: remove");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr,"usage: %s path\n",argv[0]);
exit(1);
}
// Delete the directory and its contents by traversing the tree in reverse order, without crossing mount boundaries and symbolic links
if (nftw(argv[1], rmFiles,10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
{
perror("ERROR: ntfw");
exit(1);
}
return 0;
}
★★★unix
- 시스템 라이크 시스템(- 라이크 시스템(- 라이크 시스템)Linux
, . . . . . . . .BSD
§OS X
는 '적어도'를 있다.fts
이치노
디렉토리를 반복적으로 삭제하려면 깊이 우선 트래버설(다음 심볼링크 없음)을 수행하여 방문한 모든 파일을 삭제합니다.
int recursive_delete(const char *dir)
{
int ret = 0;
FTS *ftsp = NULL;
FTSENT *curr;
// Cast needed (in C) because fts_open() takes a "char * const *", instead
// of a "const char * const *", which is only allowed in C++. fts_open()
// does not modify the argument.
char *files[] = { (char *) dir, NULL };
// FTS_NOCHDIR - Avoid changing cwd, which could cause unexpected behavior
// in multithreaded programs
// FTS_PHYSICAL - Don't follow symlinks. Prevents deletion of files outside
// of the specified directory
// FTS_XDEV - Don't cross filesystem boundaries
ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
if (!ftsp) {
fprintf(stderr, "%s: fts_open failed: %s\n", dir, strerror(errno));
ret = -1;
goto finish;
}
while ((curr = fts_read(ftsp))) {
switch (curr->fts_info) {
case FTS_NS:
case FTS_DNR:
case FTS_ERR:
fprintf(stderr, "%s: fts_read error: %s\n",
curr->fts_accpath, strerror(curr->fts_errno));
break;
case FTS_DC:
case FTS_DOT:
case FTS_NSOK:
// Not reached unless FTS_LOGICAL, FTS_SEEDOT, or FTS_NOSTAT were
// passed to fts_open()
break;
case FTS_D:
// Do nothing. Need depth-first search, so directories are deleted
// in FTS_DP
break;
case FTS_DP:
case FTS_F:
case FTS_SL:
case FTS_SLNONE:
case FTS_DEFAULT:
if (remove(curr->fts_accpath) < 0) {
fprintf(stderr, "%s: Failed to remove: %s\n",
curr->fts_path, strerror(curr->fts_errno));
ret = -1;
}
break;
}
}
finish:
if (ftsp) {
fts_close(ftsp);
}
return ret;
}
디렉토리의 자식을 열거하는 함수(재귀 함수가 가장 쉬우나 딥 디렉토리의 스택 공간이 쉽게 부족해질 수 있음)를 작성하려고 합니다.디렉토리인 하위 항목이 발견되면 해당 항목이 반복됩니다.그렇지 않으면 안에 있는 파일을 삭제합니다.작업이 완료되면 디렉토리가 비어 있으므로 syscall을 통해 삭제할 수 있습니다.
의 하려면 , 를 합니다.opendir()
,readdir()
, , , , 입니다.closedir()
하려면 , 를 사용합니다rmdir()
기능 후) 및 """ (자녀 삭제 후)"" 。unlink()
파일에 저장해당.에서 " " "는d_type
in의 struct dirent
에서는, 「」를 사용할 .이러한 플랫폼에서는stat()
★★★★★★★★★★★★★★★★★」S_ISDIR(stat.st_mode)
지정된 경로가 디렉토리인지 확인합니다.
에서는, 의 「」를 사용합니다.FindFirstFile()
/FindNextFile()
RemoveDirectory()
및 「」, 「」에 DeleteFile()
파일을 삭제합니다.
다음은 Unix(완전히 테스트되지 않음)에서 작동하는 예입니다.
int remove_directory(const char *path) {
DIR *d = opendir(path);
size_t path_len = strlen(path);
int r = -1;
if (d) {
struct dirent *p;
r = 0;
while (!r && (p=readdir(d))) {
int r2 = -1;
char *buf;
size_t len;
/* Skip the names "." and ".." as we don't want to recurse on them. */
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
continue;
len = path_len + strlen(p->d_name) + 2;
buf = malloc(len);
if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", path, p->d_name);
if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode))
r2 = remove_directory(buf);
else
r2 = unlink(buf);
}
free(buf);
}
r = r2;
}
closedir(d);
}
if (!r)
r = rmdir(path);
return r;
}
에는 C++17'이 있습니다.<experimental\filesystem>
부스트 버전을 기반으로 합니다.
std::experimental::filesystem::remove_all을 사용하여 재귀적으로 삭제합니다.
제어가 더 필요한 경우 std::experimental::filesystem::recursive_directory_iterator를 사용해 보십시오.
또한 반복기의 비재귀 버전을 사용하여 사용자 고유의 재귀를 쓸 수도 있습니다.
namespace fs = std::experimental::filesystem;
void IterateRecursively(fs::path path)
{
if (fs::is_directory(path))
{
for (auto & child : fs::directory_iterator(path))
IterateRecursively(child.path());
}
std::cout << path << std::endl;
}
가장 쉬운 방법은 Boost의 remove_all 기능을 사용하는 것입니다.파일 시스템 라이브러리게다가 결과 코드는 휴대할 수 있게 됩니다.
Unix(rmdir) 또는 Windows(RemoveDirectory) 전용으로 쓰려면 하위 파일과 하위 폴더를 반복적으로 삭제하는 함수를 작성해야 합니다.
편집
이 질문은 이미 한 것 같습니다.실제로 누군가가 이미 Boost의 remove_all을 추천했습니다.그러니 제발 내 대답을 무시하지 말아줘.
opendir 및 readdir를 사용하여 디렉토리 엔트리를 읽고 링크를 해제하여 삭제할 수 있습니다.
//======================================================
// Recursely Delete files using:
// Gnome-Glib & C++11
//======================================================
#include <iostream>
#include <string>
#include <glib.h>
#include <glib/gstdio.h>
using namespace std;
int DirDelete(const string& path)
{
const gchar* p;
GError* gerr;
GDir* d;
int r;
string ps;
string path_i;
cout << "open:" << path << "\n";
d = g_dir_open(path.c_str(), 0, &gerr);
r = -1;
if (d) {
r = 0;
while (!r && (p=g_dir_read_name(d))) {
ps = string{p};
if (ps == "." || ps == "..") {
continue;
}
path_i = path + string{"/"} + p;
if (g_file_test(path_i.c_str(), G_FILE_TEST_IS_DIR) != 0) {
cout << "recurse:" << path_i << "\n";
r = DirDelete(path_i);
}
else {
cout << "unlink:" << path_i << "\n";
r = g_unlink(path_i.c_str());
}
}
g_dir_close(d);
}
if (r == 0) {
r = g_rmdir(path.c_str());
cout << "rmdir:" << path << "\n";
}
return r;
}
c의 unlinkat()를 사용하여 비어있지 않은 폴더를 삭제하려면 어떻게 해야 합니까?
다음은 제 연구 결과입니다.
/*
* Program to erase the files/subfolders in a directory given as an input
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void remove_dir_content(const char *path)
{
struct dirent *de;
char fname[300];
DIR *dr = opendir(path);
if(dr == NULL)
{
printf("No file or directory found\n");
return;
}
while((de = readdir(dr)) != NULL)
{
int ret = -1;
struct stat statbuf;
sprintf(fname,"%s/%s",path,de->d_name);
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
if(!stat(fname, &statbuf))
{
if(S_ISDIR(statbuf.st_mode))
{
printf("Is dir: %s\n",fname);
printf("Err: %d\n",ret = unlinkat(dirfd(dr),fname,AT_REMOVEDIR));
if(ret != 0)
{
remove_dir_content(fname);
printf("Err: %d\n",ret = unlinkat(dirfd(dr),fname,AT_REMOVEDIR));
}
}
else
{
printf("Is file: %s\n",fname);
printf("Err: %d\n",unlink(fname));
}
}
}
closedir(dr);
}
void main()
{
char str[10],str1[20] = "../",fname[300]; // Use str,str1 as your directory path where it's files & subfolders will be deleted.
printf("Enter the dirctory name: ");
scanf("%s",str);
strcat(str1,str);
printf("str1: %s\n",str1);
remove_dir_content(str1); //str1 indicates the directory path
}
언급URL : https://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c
'programing' 카테고리의 다른 글
기호별 또는 크기별 유형이 아닌 "int"를 사용해야 할 때는 언제입니까? (0) | 2022.08.08 |
---|---|
Vue가 동적 구성 요소를 사용하여 Vuex에서 v-for의 항목을 업데이트하지 않음 (0) | 2022.08.08 |
Vuex getter 반환 정의되지 않은 값 (0) | 2022.08.08 |
Java에서 클래스를 스태틱으로 선언할 수 없는 이유는 무엇입니까? (0) | 2022.08.08 |
__stdcall이 뭐죠? (0) | 2022.08.08 |