我需要用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
如果它前面有文件,则意味着它是从If(SúISREG)使用的;如果它有文件夹,则意味着它是从If(SúISDIR)使用的。所以至少现在它认识到test1和test2是文件,但它仍然将它们复制为文件夹。
最佳答案
必须切换控制语句:首先查看它是否是文件,然后检查它是否是目录
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;
}