如何在C ++ / Linux中创建目录树? [英] How can I create directory tree in C++/Linux?
问题描述
我想要一种在C ++ / Linux中创建多个目录的简单方法。
I want an easy way to create multiple directories in C++/Linux.
例如,我要在目录中保存一个文件lola.file:
For example I want to save a file lola.file in the directory:
/tmp/a/b/c
但是如果目录不在那里他们自动创建。一个工作示例是完美的。
but if the directories are not there I want them to be created automagically. A working example would be perfect.
推荐答案
这里是一个C函数,可以用C ++编译器编译。
Here's a C function that can be compiled with C++ compilers.
/*
@(#)File: $RCSfile: mkpath.c,v $
@(#)Version: $Revision: 1.13 $
@(#)Last changed: $Date: 2012/07/15 00:40:37 $
@(#)Purpose: Create all directories in path
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 1990-91,1997-98,2001,2005,2008,2012
*/
/*TABSTOP=4*/
#include "jlss.h"
#include "emalloc.h"
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <string.h>
#include "sysstat.h" /* Fix up for Windows - inc mode_t */
typedef struct stat Stat;
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_mkpath_c[] = "@(#)$Id: mkpath.c,v 1.13 2012/07/15 00:40:37 jleffler Exp $";
#endif /* lint */
static int do_mkdir(const char *path, mode_t mode)
{
Stat st;
int status = 0;
if (stat(path, &st) != 0)
{
/* Directory does not exist. EEXIST for race condition */
if (mkdir(path, mode) != 0 && errno != EEXIST)
status = -1;
}
else if (!S_ISDIR(st.st_mode))
{
errno = ENOTDIR;
status = -1;
}
return(status);
}
/**
** mkpath - ensure all directories in path exist
** Algorithm takes the pessimistic view and works top-down to ensure
** each directory in path exists, rather than optimistically creating
** the last element and working backwards.
*/
int mkpath(const char *path, mode_t mode)
{
char *pp;
char *sp;
int status;
char *copypath = STRDUP(path);
status = 0;
pp = copypath;
while (status == 0 && (sp = strchr(pp, '/')) != 0)
{
if (sp != pp)
{
/* Neither root nor double slash in path */
*sp = '\0';
status = do_mkdir(copypath, mode);
*sp = '/';
}
pp = sp + 1;
}
if (status == 0)
status = do_mkdir(path, mode);
FREE(copypath);
return (status);
}
#ifdef TEST
#include <stdio.h>
/*
** Stress test with parallel running of mkpath() function.
** Before the EEXIST test, code would fail.
** With the EEXIST test, code does not fail.
**
** Test shell script
** PREFIX=mkpath.$$
** NAME=./$PREFIX/sa/32/ad/13/23/13/12/13/sd/ds/ww/qq/ss/dd/zz/xx/dd/rr/ff/ff/ss/ss/ss/ss/ss/ss/ss/ss
** : ${MKPATH:=mkpath}
** ./$MKPATH $NAME &
** [...repeat a dozen times or so...]
** ./$MKPATH $NAME &
** wait
** rm -fr ./$PREFIX/
*/
int main(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
{
for (int j = 0; j < 20; j++)
{
if (fork() == 0)
{
int rc = mkpath(argv[i], 0777);
if (rc != 0)
fprintf(stderr, "%d: failed to create (%d: %s): %s\n",
(int)getpid(), errno, strerror(errno), argv[i]);
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
}
int status;
int fail = 0;
while (wait(&status) != -1)
{
if (WEXITSTATUS(status) != 0)
fail = 1;
}
if (fail == 0)
printf("created: %s\n", argv[i]);
}
return(0);
}
#endif /* TEST */
宏 STRDUP()
和 FREE()
是错误检查版本 strdup / code>中声明的
和
和
和 free()
c> emalloc.c estrdup.c
)。 sysstat.h
头处理< sys / stat.h>
的破坏版本,在现代Unix系统上( c>< sys / stat.h> jlss.h
声明 mkpath()
。
The macros STRDUP()
and FREE()
are error-checking versions of strdup()
and free()
, declared in emalloc.h
(and implemented in emalloc.c
and estrdup.c
). The "sysstat.h"
header deals with broken versions of <sys/stat.h>
and can be replaced by <sys/stat.h>
on modern Unix systems (but there were many issues back in 1990). And "jlss.h"
declares mkpath()
.
在v1.12(上一个)和v1.13(上面)之间的变化是 EEXIST
在中的测试do_mkdir()
。 切换—谢谢,开关。测试代码已经升级并在MacBook Pro(2.3GHz Intel Core i7,运行Mac OS X 10.7.4)上重现了这个问题,并建议问题在修订版本中修复(但测试只能显示错误的存在
The change between v1.12 (previous) and v1.13 (above) is the test for EEXIST
in do_mkdir()
. This was pointed out as necessary by Switch — thank you, Switch. The test code has been upgraded and reproduced the problem on a MacBook Pro (2.3GHz Intel Core i7, running Mac OS X 10.7.4), and suggests that the problem is fixed in the revision (but testing can only show the presence of bugs, never their absence).
这篇关于如何在C ++ / Linux中创建目录树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!