การสร้างไดเร็กทอรีใหม่ใน C


99

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

ฉันจะทำสิ่งนี้ใน C กับ Linux ได้อย่างไร


1
ฟังก์ชัน mkdir สร้างไดเรกทอรีใหม่blog.tremend.ro/2008/10/06/…
fsonmezay

1
บางทีนั่นอาจจะเพราะคุณสามารถหาทางออกใน Google หรือแม้กระทั่งในที่นี่โดยการค้นหาง่ายstackoverflow.com/search?q=C+make+directory ยังไงซะฉันก็ไม่ใช่คนที่โหวตไม่ลง
fsonmezay

โปรดแก้ไขคำถามของคุณเพื่อแสดงรหัสที่คุณมีจนถึงตอนนี้ คุณควรใส่เค้าโครงอย่างน้อย (แต่ควรเป็นตัวอย่างที่สามารถทำซ้ำได้น้อยที่สุด ) ของโค้ดที่คุณมีปัญหาจากนั้นเราจะพยายามช่วยแก้ปัญหานั้น ๆ คุณควรอ่านวิธีถามด้วย
Toby Speight

คำตอบ:


152

มองไปที่statการตรวจสอบถ้าไดเรกทอรีที่มีอยู่

และmkdirเพื่อสร้างไดเร็กทอรี

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat st = {0};

if (stat("/some/directory", &st) == -1) {
    mkdir("/some/directory", 0700);
}

คุณสามารถดูคู่มือของฟังก์ชันเหล่านี้ด้วยคำสั่งman 2 statandman 2 mkdir


5
ฉันเชื่อว่าmkdirภายใต้ Linux ต้องการพารามิเตอร์ที่สองmodeนอกเหนือจากpath.
Paul R

1
@Uku: การส่งพารามิเตอร์ที่ไม่ถูกต้องไปยังฟังก์ชันเป็นพฤติกรรมที่ไม่ได้กำหนดดังนั้นในขณะที่ดูเหมือนว่าจะได้ผลสำหรับคุณในกรณีเดียวคุณไม่ควรพึ่งพามัน
Paul R

3
จุดประสงค์ของการตรวจสอบว่าไม่มีไดเร็กทอรีก่อนสร้างขึ้นมาคืออะไร? แม้ว่า stat จะบอกว่ายังไม่มีอยู่ แต่กระบวนการอื่นอาจสร้างขึ้นในระหว่างนี้
Brandin

2
@ แบรนดินฉันเดาว่าฉันตอบคำถามของ OP อย่างสุ่มสี่สุ่มห้า :) คุณพูดถูกเกี่ยวกับสภาพการแข่งขัน
Arnaud Le Blanc

4
สิ่งนี้จะถูกตั้งค่าสถานะโดยนักวิเคราะห์แบบคงที่ที่ดีที่สุดว่าเป็นความเสี่ยง
TOCTOU

22

คุณสามารถใช้ mkdir:

$ man 2 mkdir

#include <sys/stat.h>
#include <sys/types.h>

int result = mkdir("/home/me/test.txt", 0777);

สิ่งนี้จะลบและแทนที่ไดเรกทอรีที่มีอยู่หรือไม่?
jjxtra

@jjxtra :: ไม่ควรล้มเหลวหากมีไดเร็กทอรีอยู่แล้วในลักษณะเดียวกับที่คุณพยายามดำเนินการเดียวกันจากบรรทัดคำสั่ง
Paul R

นั่นคือสิ่งที่ฉันพอจะเดาได้ มีปัญหาด้านประสิทธิภาพโดยข้ามการตรวจสอบสถิติและเพียงแค่ mkdir ทุกครั้ง?
jjxtra

@jjxtra: เว้นแต่คุณจะสร้างไดเรกทอรีหลายพันรายการฉันนึกไม่ถึงว่าจะมีความแตกต่างด้านประสิทธิภาพที่วัดได้
Paul R

7

ฉันต้องการเขียนโปรแกรมที่ (... ) สร้างไดเร็กทอรีและไฟล์ (... ) อยู่ข้างใน

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

void rek_mkdir(char *path) {
    char *sep = strrchr(path, '/');
    if(sep != NULL) {
        *sep = 0;
        rek_mkdir(path);
        *sep = '/';
    }
    if(mkdir(path, 0777) && errno != EEXIST)
        printf("error while trying to create '%s'\n%m\n", path); 
}

FILE *fopen_mkdir(char *path, char *mode) {
    char *sep = strrchr(path, '/');
    if(sep) { 
        char *path0 = strdup(path);
        path0[ sep - path ] = 0;
        rek_mkdir(path0);
        free(path0);
    }
    return fopen(path,mode);
}

3
เพียงแค่ 5 เซ็นต์ของฉัน - โหมด 0777 สำหรับ dir อาจไม่ต้องการ - บางที 0755 จะดีกว่าหรือแม้กระทั่งผ่านพารามิเตอร์?
ivan.ukr

@ ivan.ukr 0777 ถูกต้องโหมดจะแก้ไขโดยผู้ใช้ umask เช่น. สำหรับ umask 022 ได้ผลลัพธ์เป็น 755 หรือสำหรับ umask 007 ใน 770
imix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.