c S_ISDIR和S_ISREG无效

时间:2017-05-29 09:41:58

标签: c linux file-type

我需要使用C在linux中创建应用程序,我需要输入文件夹路径并将所有文件和子目录复制到新文件夹中。 问题是当我尝试检查路径是否是文件夹或文件时,程序始终将路径视为文件夹,即使它是文件。我不知道我做错了什么。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>

int main()
{
    CopyFile("test3","test4");
    return (0);
}

void mkdirRecursive(const char *path, mode_t mode) {
    char opath[PATH_MAX];
    char *p;
    size_t len;

    strncpy(opath, path, sizeof(opath));
    opath[sizeof(opath) - 1] = '\0';
    len = strlen(opath);
    if (len == 0)
        return;
    else if (opath[len - 1] == '/')
        opath[len - 1] = '\0';
    for(p = opath; *p; p++)
        if (*p == '/') {
            *p = '\0';
            if (access(opath, F_OK))
                mkdir(opath, mode);
            *p = '/';
        }
    if (access(opath, F_OK))         
        mkdir(opath, mode);
}

void CopyFile(char* NumeFisOld, char* NumeFisNew)
{


    DIR *dp;
    struct dirent *dirp;
    struct stat info;
    char OldDirPath[255];
    char NewDirPath[255];
    stat(NumeFisOld,&info);
    int status = stat (NumeFisOld, &info);
    if (status != 0) 
    {
        fprintf (stderr, "Error, errno = %d\n", errno);
        perror("stat error: ");
        return;
    }
    fprintf (stderr, "Error, errno = %d\n", errno);
    perror("stat error: ");
    if(S_ISREG(info.st_mode))
    {
        printf("File: File location: %s \n",NumeFisOld);
        printf("File: New file location: %s \n",NumeFisNew);
        char buffer[65];
        int fhRead;
        int fhWrite;
        unsigned int nbytes=65;
        int bytesread;
        int byteswritten;
        if((fhRead=open(NumeFisOld, O_RDONLY)) ==-1)
        {
            perror("Eroare la deschiderea fisierului");
            exit(1);
        }

        if((bytesread=read(fhRead,buffer,nbytes))<=0)
            perror("Probleme la citirea fisierului");
        else
            printf("Citeste %u bytes din fisier\n", bytesread);

        close(fhRead);
        if((fhWrite=open(NumeFisNew,O_WRONLY | O_CREAT,S_IREAD | S_IWRITE)) !=-1) 
        {
            if((byteswritten=write(fhWrite, buffer, sizeof(buffer))) == -1)
                perror("Eroare la scriere");
            else
                printf("A scris %u bytes in fisier\n",byteswritten);
            close(fhWrite);
        }

    }
    else if(S_ISDIR(info.st_mode))
    {
        printf("Folder: File location: %s \n",NumeFisOld);
        printf("Folder: New file location: %s \n",NumeFisNew);
        dp=opendir(NumeFisOld);
        while((dirp=readdir(dp)) != NULL)
        {

            strcpy(OldDirPath, NumeFisOld);
            strcat(OldDirPath,"/");
            strcat(OldDirPath,dirp->d_name);
            strcpy(NewDirPath, NumeFisNew);
            strcat(NewDirPath, "/");
            strcat(NewDirPath,dirp->d_name);
            DIR* dir = opendir(NewDirPath);
            if(dirp->d_name[0]!='.') 
            {
                if (dir)
                {
                    /* Directonry exists. */
                    CopyFile (OldDirPath,NewDirPath);
                    printf("Directorul %s exista deja \n",NewDirPath);
                    closedir(dir);
                }
                else if (ENOENT == errno)
                {

                    printf("Directorul %s nu exista \n",NewDirPath);
                    mkdirRecursive(NewDirPath,0755);
                    CopyFile (OldDirPath,NewDirPath);
                    /* Directory does not exist. */
                }
                else
                {
                    printf("Directorul %s nu s-a putut deschide \n",NewDirPath);
                    /* opendir() failed for some other reason. */
                }
            }

        }


    }

}

我的逻辑是:首先我检查路径是否是目录,如果是,在我的新文件夹(NumeFisNew)中创建它然后输入它(NumeFisOld)并重复其中的每个子目录或文件。如果路径是文件,那么它应该输入else并在路径中复制文件(NumeFisNew)。

编辑: 好的,结果如下:

Error, errno = 0
stat error: : Success
Folder: File location: test3 
Folder: New file location: test4 
Error, errno = 0
stat error: : Success
Folder: File location: test3/test5 
Folder: New file location: test4/test5 
Directorul test4/test5 exista deja 
Error, errno = 0
stat error: : Success
Folder: File location: test3/test4 
Folder: New file location: test4/test4 
Error, errno = 0
stat error: : Success
File: File location: test3/test4/test2 
File: New file location: test4/test4/test2 
Citeste 42 bytes din fisier
Directorul test4/test4/test2 exista deja 
Directorul test4/test4 exista deja 
Error, errno = 21
stat error: : Is a directory
File: File location: test3/test1 
File: New file location: test4/test1 
Citeste 42 bytes din fisier
Directorul test4/test1 exista deja 

如果前面有File,则表示它是从if(S_ISREG)使用的,如果它有Folder,则表示它是从if(S_ISDIR)使用的。所以至少现在它认识到test1和test2是文件,但它仍然将它们复制为文件夹。

1 个答案:

答案 0 :(得分:0)

您必须切换控制语句:首先查看它是否是文件,并在检查后是否为目录

if (S_ISREG (info.st_mode)) 
{
    printf ("It's a file\n");
}
else if (S_ISDIR (info.st_mode)) 
{
    printf ("It's a dir\n");
}

此外,您应该注意统计返回值

int status = stat (NumeFisOld, &info);
if (status != 0) 
{
    fprintf (stderr, "Error, errno = %d\n", errno);
    perror("stat error: ");
    return;
}